@mieweb/ui 0.10.0-dev.3 → 0.10.0-dev.30
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.
- package/README.md +4 -4
- package/agent/mieweb-ui.instructions.md +90 -1
- package/dist/CsvBlock-FX5YNGNE.cjs +17 -0
- package/dist/{CsvBlock-ROJCKJDP.cjs.map → CsvBlock-FX5YNGNE.cjs.map} +1 -1
- package/dist/CsvBlock-VLMG7GUO.js +8 -0
- package/dist/{CsvBlock-UWPMTLE2.js.map → CsvBlock-VLMG7GUO.js.map} +1 -1
- package/dist/HtmlPreviewBlock-5JE7L3GR.js +8 -0
- package/dist/{HtmlPreviewBlock-ME5U3XNS.js.map → HtmlPreviewBlock-5JE7L3GR.js.map} +1 -1
- package/dist/HtmlPreviewBlock-UO37JQ3K.cjs +17 -0
- package/dist/{HtmlPreviewBlock-DWFN6EUB.cjs.map → HtmlPreviewBlock-UO37JQ3K.cjs.map} +1 -1
- package/dist/Input-yN516s5_.d.cts +3 -0
- package/dist/Input-yN516s5_.d.ts +3 -0
- package/dist/MermaidBlock-3XHFBAMV.js +8 -0
- package/dist/{MermaidBlock-2B6CPD6Y.js.map → MermaidBlock-3XHFBAMV.js.map} +1 -1
- package/dist/MermaidBlock-RZ75RPZA.cjs +17 -0
- package/dist/{MermaidBlock-D2UC5M55.cjs.map → MermaidBlock-RZ75RPZA.cjs.map} +1 -1
- package/dist/SurveyBlock-MUVJ3JUI.js +8 -0
- package/dist/{SurveyBlock-4DO62RBT.js.map → SurveyBlock-MUVJ3JUI.js.map} +1 -1
- package/dist/SurveyBlock-VH47YXZC.cjs +17 -0
- package/dist/{SurveyBlock-4CD4AYMJ.cjs.map → SurveyBlock-VH47YXZC.cjs.map} +1 -1
- package/dist/ag-grid.d.cts +142 -1
- package/dist/ag-grid.d.ts +142 -1
- package/dist/brands/bluehive.cjs +3 -3
- package/dist/brands/bluehive.css +3 -0
- package/dist/brands/bluehive.js +1 -1
- package/dist/brands/index.cjs +14 -14
- package/dist/brands/index.js +4 -4
- package/dist/{chunk-JYZW2PZS.cjs → chunk-254QK722.cjs} +7 -7
- package/dist/chunk-254QK722.cjs.map +1 -0
- package/dist/{chunk-VKELAMAZ.js → chunk-2JICT4A2.js} +27 -11
- package/dist/chunk-2JICT4A2.js.map +1 -0
- package/dist/{chunk-VPWJCJCX.cjs → chunk-35Y4ILCU.cjs} +7 -7
- package/dist/{chunk-VPWJCJCX.cjs.map → chunk-35Y4ILCU.cjs.map} +1 -1
- package/dist/{chunk-G3JX3UAU.cjs → chunk-3KPDQG5O.cjs} +5 -5
- package/dist/{chunk-G3JX3UAU.cjs.map → chunk-3KPDQG5O.cjs.map} +1 -1
- package/dist/{chunk-Y5HFM7LO.js → chunk-3RXZWHCU.js} +4 -4
- package/dist/{chunk-Y5HFM7LO.js.map → chunk-3RXZWHCU.js.map} +1 -1
- package/dist/chunk-3YBS4WUQ.js +52 -0
- package/dist/chunk-3YBS4WUQ.js.map +1 -0
- package/dist/{chunk-WNJRS7Y7.cjs → chunk-3ZWCIPFT.cjs} +4 -2
- package/dist/chunk-3ZWCIPFT.cjs.map +1 -0
- package/dist/chunk-4HC2IBOX.js +258 -0
- package/dist/chunk-4HC2IBOX.js.map +1 -0
- package/dist/chunk-4IS3QCOQ.cjs +453 -0
- package/dist/chunk-4IS3QCOQ.cjs.map +1 -0
- package/dist/chunk-4NCDU5IG.cjs +56 -0
- package/dist/chunk-4NCDU5IG.cjs.map +1 -0
- package/dist/{chunk-E4IBHYJ7.cjs → chunk-6N6LIAUJ.cjs} +9 -9
- package/dist/{chunk-E4IBHYJ7.cjs.map → chunk-6N6LIAUJ.cjs.map} +1 -1
- package/dist/{chunk-3M7TAXNR.js → chunk-6ZPTZTKN.js} +3 -3
- package/dist/{chunk-3M7TAXNR.js.map → chunk-6ZPTZTKN.js.map} +1 -1
- package/dist/{chunk-MWVW4APN.cjs → chunk-7UTBDFFL.cjs} +4 -4
- package/dist/{chunk-MWVW4APN.cjs.map → chunk-7UTBDFFL.cjs.map} +1 -1
- package/dist/{chunk-FJ7YPVKV.js → chunk-7X6R3JIA.js} +3 -3
- package/dist/{chunk-FJ7YPVKV.js.map → chunk-7X6R3JIA.js.map} +1 -1
- package/dist/{chunk-GOALNQZ2.js → chunk-7YO7DNUV.js} +4 -83
- package/dist/chunk-7YO7DNUV.js.map +1 -0
- package/dist/{chunk-P2CA3XGI.js → chunk-7ZV67VZE.js} +4 -4
- package/dist/{chunk-P2CA3XGI.js.map → chunk-7ZV67VZE.js.map} +1 -1
- package/dist/chunk-ADW7ZYCY.cjs +2707 -0
- package/dist/chunk-ADW7ZYCY.cjs.map +1 -0
- package/dist/{chunk-2G75X6TS.cjs → chunk-AHHFFXJR.cjs} +3 -3
- package/dist/{chunk-2G75X6TS.cjs.map → chunk-AHHFFXJR.cjs.map} +1 -1
- package/dist/{chunk-VILW53UZ.js → chunk-BIQ7GSO2.js} +3 -3
- package/dist/{chunk-VILW53UZ.js.map → chunk-BIQ7GSO2.js.map} +1 -1
- package/dist/chunk-BM35CACB.js +148 -0
- package/dist/chunk-BM35CACB.js.map +1 -0
- package/dist/chunk-BNH4SXJB.js +874 -0
- package/dist/chunk-BNH4SXJB.js.map +1 -0
- package/dist/{chunk-XEAT7XJG.cjs → chunk-BUT6MF5K.cjs} +29 -13
- package/dist/chunk-BUT6MF5K.cjs.map +1 -0
- package/dist/{chunk-UAMXCMST.cjs → chunk-CFI3TQMA.cjs} +3 -3
- package/dist/{chunk-UAMXCMST.cjs.map → chunk-CFI3TQMA.cjs.map} +1 -1
- package/dist/{chunk-J5CSLNCN.cjs → chunk-COM7RNZU.cjs} +2 -2
- package/dist/{chunk-J5CSLNCN.cjs.map → chunk-COM7RNZU.cjs.map} +1 -1
- package/dist/{chunk-XI34EGK5.cjs → chunk-CPPUT74P.cjs} +9 -9
- package/dist/{chunk-XI34EGK5.cjs.map → chunk-CPPUT74P.cjs.map} +1 -1
- package/dist/{chunk-ACCAXVOG.js → chunk-CRS2CQWM.js} +134 -56
- package/dist/chunk-CRS2CQWM.js.map +1 -0
- package/dist/{chunk-OE5CKRUC.js → chunk-D22GE27K.js} +4 -4
- package/dist/{chunk-OE5CKRUC.js.map → chunk-D22GE27K.js.map} +1 -1
- package/dist/chunk-DXEPYK3I.cjs +92 -0
- package/dist/chunk-DXEPYK3I.cjs.map +1 -0
- package/dist/{chunk-ZGRCSNPK.js → chunk-E2PBPQGS.js} +4 -4
- package/dist/{chunk-ZGRCSNPK.js.map → chunk-E2PBPQGS.js.map} +1 -1
- package/dist/{chunk-5JJ2DAE4.js → chunk-ENMXHZNE.js} +3 -3
- package/dist/{chunk-5JJ2DAE4.js.map → chunk-ENMXHZNE.js.map} +1 -1
- package/dist/{chunk-XCP454Q6.js → chunk-F4N67NAF.js} +12 -3
- package/dist/chunk-F4N67NAF.js.map +1 -0
- package/dist/chunk-FBCDYTWM.js +385 -0
- package/dist/chunk-FBCDYTWM.js.map +1 -0
- package/dist/{chunk-VU6UTJRM.js → chunk-FIKO4WR6.js} +3 -3
- package/dist/{chunk-VU6UTJRM.js.map → chunk-FIKO4WR6.js.map} +1 -1
- package/dist/{chunk-DEDN5HAG.js → chunk-FZURBQJ2.js} +3 -3
- package/dist/{chunk-DEDN5HAG.js.map → chunk-FZURBQJ2.js.map} +1 -1
- package/dist/{chunk-JHULS3EC.js → chunk-GBUVIGD5.js} +89 -3
- package/dist/chunk-GBUVIGD5.js.map +1 -0
- package/dist/chunk-GU5OS7JJ.cjs +281 -0
- package/dist/chunk-GU5OS7JJ.cjs.map +1 -0
- package/dist/{chunk-V7D3YGUV.js → chunk-GVLNXPJX.js} +4 -4
- package/dist/{chunk-V7D3YGUV.js.map → chunk-GVLNXPJX.js.map} +1 -1
- package/dist/chunk-GVM6DTR5.js +90 -0
- package/dist/chunk-GVM6DTR5.js.map +1 -0
- package/dist/{chunk-SQHMGT4W.js → chunk-GW4RFJZ5.js} +7 -7
- package/dist/chunk-GW4RFJZ5.js.map +1 -0
- package/dist/{chunk-3QEVGSFG.cjs → chunk-GYXUS65N.cjs} +5 -5
- package/dist/{chunk-3QEVGSFG.cjs.map → chunk-GYXUS65N.cjs.map} +1 -1
- package/dist/{chunk-WGPLUCBD.js → chunk-H2IAMSHK.js} +3 -3
- package/dist/{chunk-WGPLUCBD.js.map → chunk-H2IAMSHK.js.map} +1 -1
- package/dist/{chunk-JID7AZTO.cjs → chunk-H3ROMJYI.cjs} +4 -4
- package/dist/{chunk-JID7AZTO.cjs.map → chunk-H3ROMJYI.cjs.map} +1 -1
- package/dist/{chunk-GD7EBGC4.cjs → chunk-HC3NAN55.cjs} +19 -19
- package/dist/{chunk-GD7EBGC4.cjs.map → chunk-HC3NAN55.cjs.map} +1 -1
- package/dist/{chunk-7ZXAQTV4.cjs → chunk-HIZWOAWY.cjs} +8 -8
- package/dist/{chunk-7ZXAQTV4.cjs.map → chunk-HIZWOAWY.cjs.map} +1 -1
- package/dist/{chunk-NV2CWBI2.cjs → chunk-IEY3ZJIT.cjs} +12 -3
- package/dist/chunk-IEY3ZJIT.cjs.map +1 -0
- package/dist/chunk-IT775BYG.js +179 -0
- package/dist/chunk-IT775BYG.js.map +1 -0
- package/dist/chunk-IYWG72DM.js +166 -0
- package/dist/chunk-IYWG72DM.js.map +1 -0
- package/dist/{chunk-2YCERQWC.js → chunk-JBIGSP2T.js} +6 -6
- package/dist/{chunk-2YCERQWC.js.map → chunk-JBIGSP2T.js.map} +1 -1
- package/dist/{chunk-IX6KFB3K.cjs → chunk-JELTRRR5.cjs} +9 -9
- package/dist/{chunk-IX6KFB3K.cjs.map → chunk-JELTRRR5.cjs.map} +1 -1
- package/dist/{chunk-YQDA366U.js → chunk-JHG3ELS2.js} +2 -2
- package/dist/{chunk-YQDA366U.js.map → chunk-JHG3ELS2.js.map} +1 -1
- package/dist/{chunk-WWJIW2IH.cjs → chunk-JSXIB6EJ.cjs} +4 -4
- package/dist/{chunk-WWJIW2IH.cjs.map → chunk-JSXIB6EJ.cjs.map} +1 -1
- package/dist/{chunk-WNM7IZJ7.js → chunk-K34DXMLZ.js} +7 -7
- package/dist/{chunk-WNM7IZJ7.js.map → chunk-K34DXMLZ.js.map} +1 -1
- package/dist/{chunk-FXO5ARBB.cjs → chunk-KDW6BD4O.cjs} +4 -4
- package/dist/{chunk-FXO5ARBB.cjs.map → chunk-KDW6BD4O.cjs.map} +1 -1
- package/dist/{chunk-Z5V7SAZ4.js → chunk-KFEN2SRZ.js} +3 -3
- package/dist/{chunk-Z5V7SAZ4.js.map → chunk-KFEN2SRZ.js.map} +1 -1
- package/dist/{chunk-2QKBTPUC.cjs → chunk-KGKBZN3T.cjs} +8 -8
- package/dist/{chunk-2QKBTPUC.cjs.map → chunk-KGKBZN3T.cjs.map} +1 -1
- package/dist/{chunk-UV2FVNWT.cjs → chunk-LFPJ3OUM.cjs} +5 -5
- package/dist/{chunk-UV2FVNWT.cjs.map → chunk-LFPJ3OUM.cjs.map} +1 -1
- package/dist/{chunk-WNAA6CLE.cjs → chunk-LHBWRMNC.cjs} +94 -2
- package/dist/chunk-LHBWRMNC.cjs.map +1 -0
- package/dist/{chunk-JI244Y7C.js → chunk-MLAWXPRY.js} +190 -5
- package/dist/chunk-MLAWXPRY.js.map +1 -0
- package/dist/chunk-N7C4OEP7.cjs +356 -0
- package/dist/chunk-N7C4OEP7.cjs.map +1 -0
- package/dist/{chunk-WNZAYBVB.cjs → chunk-NKV76R65.cjs} +48 -48
- package/dist/{chunk-WNZAYBVB.cjs.map → chunk-NKV76R65.cjs.map} +1 -1
- package/dist/{chunk-PYJDVWXM.js → chunk-NUB5HRKS.js} +3 -3
- package/dist/{chunk-PYJDVWXM.js.map → chunk-NUB5HRKS.js.map} +1 -1
- package/dist/{chunk-LL6IWKI3.js → chunk-OW3SQJ7P.js} +3 -3
- package/dist/{chunk-LL6IWKI3.js.map → chunk-OW3SQJ7P.js.map} +1 -1
- package/dist/{chunk-5GUOOLPR.cjs → chunk-P5CMZZRZ.cjs} +5 -5
- package/dist/{chunk-5GUOOLPR.cjs.map → chunk-P5CMZZRZ.cjs.map} +1 -1
- package/dist/{chunk-3T7QGLNB.js → chunk-PJEL5ZZV.js} +4 -2
- package/dist/chunk-PJEL5ZZV.js.map +1 -0
- package/dist/{chunk-H4ZXMQQW.js → chunk-QOVJ6Z6R.js} +3 -3
- package/dist/{chunk-H4ZXMQQW.js.map → chunk-QOVJ6Z6R.js.map} +1 -1
- package/dist/{chunk-U42F3HLE.cjs → chunk-QURJVPRH.cjs} +190 -5
- package/dist/chunk-QURJVPRH.cjs.map +1 -0
- package/dist/{chunk-X4XPNTCZ.cjs → chunk-R5Z7AOVU.cjs} +136 -58
- package/dist/chunk-R5Z7AOVU.cjs.map +1 -0
- package/dist/{chunk-TMMVIUUN.js → chunk-R6KPWIGO.js} +4 -4
- package/dist/{chunk-TMMVIUUN.js.map → chunk-R6KPWIGO.js.map} +1 -1
- package/dist/{chunk-22CYDCXA.js → chunk-RM2HPQIC.js} +105 -14
- package/dist/chunk-RM2HPQIC.js.map +1 -0
- package/dist/{chunk-ENKFJJZX.js → chunk-SD7ONW6S.js} +6 -6
- package/dist/{chunk-ENKFJJZX.js.map → chunk-SD7ONW6S.js.map} +1 -1
- package/dist/{chunk-RJ6NTJHC.js → chunk-SRMTRD7F.js} +3 -3
- package/dist/{chunk-RJ6NTJHC.js.map → chunk-SRMTRD7F.js.map} +1 -1
- package/dist/chunk-T4JYUICS.js +2657 -0
- package/dist/chunk-T4JYUICS.js.map +1 -0
- package/dist/{chunk-7ZDPD5ZX.cjs → chunk-T4L7Q5FA.cjs} +7 -7
- package/dist/{chunk-7ZDPD5ZX.cjs.map → chunk-T4L7Q5FA.cjs.map} +1 -1
- package/dist/{chunk-NJ6MY6V5.js → chunk-T5BBZQ66.js} +3 -3
- package/dist/{chunk-NJ6MY6V5.js.map → chunk-T5BBZQ66.js.map} +1 -1
- package/dist/{chunk-2IZLKPUW.js → chunk-THLIL6PY.js} +3 -3
- package/dist/{chunk-2IZLKPUW.js.map → chunk-THLIL6PY.js.map} +1 -1
- package/dist/{chunk-SGFYA22I.cjs → chunk-TJCX4OML.cjs} +8 -8
- package/dist/{chunk-SGFYA22I.cjs.map → chunk-TJCX4OML.cjs.map} +1 -1
- package/dist/{chunk-N6IY47YA.cjs → chunk-TTSSUOEV.cjs} +8 -8
- package/dist/{chunk-N6IY47YA.cjs.map → chunk-TTSSUOEV.cjs.map} +1 -1
- package/dist/{chunk-5MCBWTIF.cjs → chunk-TYE5K5WV.cjs} +4 -4
- package/dist/{chunk-5MCBWTIF.cjs.map → chunk-TYE5K5WV.cjs.map} +1 -1
- package/dist/{chunk-VOKVG3ER.js → chunk-UBSH27C2.js} +4 -4
- package/dist/{chunk-VOKVG3ER.js.map → chunk-UBSH27C2.js.map} +1 -1
- package/dist/{chunk-TAXD5ADA.cjs → chunk-UEDTZYGI.cjs} +3 -3
- package/dist/{chunk-TAXD5ADA.cjs.map → chunk-UEDTZYGI.cjs.map} +1 -1
- package/dist/{chunk-UQ3VVR6A.cjs → chunk-UPWIJC6I.cjs} +3 -3
- package/dist/{chunk-UQ3VVR6A.cjs.map → chunk-UPWIJC6I.cjs.map} +1 -1
- package/dist/{chunk-S7WCHDBO.js → chunk-VCI2Y7ST.js} +3 -3
- package/dist/{chunk-S7WCHDBO.js.map → chunk-VCI2Y7ST.js.map} +1 -1
- package/dist/chunk-VINZZQBD.cjs +323 -0
- package/dist/chunk-VINZZQBD.cjs.map +1 -0
- package/dist/{chunk-OD47TTAW.cjs → chunk-VOQJHSXN.cjs} +9 -9
- package/dist/{chunk-OD47TTAW.cjs.map → chunk-VOQJHSXN.cjs.map} +1 -1
- package/dist/chunk-VPTASZ2O.cjs +171 -0
- package/dist/chunk-VPTASZ2O.cjs.map +1 -0
- package/dist/chunk-WXFGHDTV.cjs +896 -0
- package/dist/chunk-WXFGHDTV.cjs.map +1 -0
- package/dist/{chunk-VNYW4C4J.cjs → chunk-X6A27RGO.cjs} +4 -84
- package/dist/chunk-X6A27RGO.cjs.map +1 -0
- package/dist/chunk-XBTKZCZF.js +333 -0
- package/dist/chunk-XBTKZCZF.js.map +1 -0
- package/dist/chunk-XDIMTPZU.cjs +202 -0
- package/dist/chunk-XDIMTPZU.cjs.map +1 -0
- package/dist/chunk-XDU65GLW.js +21 -0
- package/dist/chunk-XDU65GLW.js.map +1 -0
- package/dist/chunk-XI74P5F2.cjs +424 -0
- package/dist/chunk-XI74P5F2.cjs.map +1 -0
- package/dist/{chunk-WIAQQNFU.cjs → chunk-XRVMYT5G.cjs} +106 -13
- package/dist/chunk-XRVMYT5G.cjs.map +1 -0
- package/dist/chunk-XVW5DPPP.js +429 -0
- package/dist/chunk-XVW5DPPP.js.map +1 -0
- package/dist/chunk-Y4E2WRUR.cjs +188 -0
- package/dist/chunk-Y4E2WRUR.cjs.map +1 -0
- package/dist/chunk-Y4QNLW7W.js +300 -0
- package/dist/chunk-Y4QNLW7W.js.map +1 -0
- package/dist/{chunk-6EN3IQQI.cjs → chunk-YRHBSSQ3.cjs} +6 -6
- package/dist/{chunk-6EN3IQQI.cjs.map → chunk-YRHBSSQ3.cjs.map} +1 -1
- package/dist/{chunk-KZFBQ7GY.js → chunk-YU55JD35.js} +3 -3
- package/dist/{chunk-KZFBQ7GY.js.map → chunk-YU55JD35.js.map} +1 -1
- package/dist/chunk-YW2AKBLS.cjs +23 -0
- package/dist/chunk-YW2AKBLS.cjs.map +1 -0
- package/dist/{chunk-ELPW32ZI.cjs → chunk-ZTMYKAVU.cjs} +45 -45
- package/dist/{chunk-ELPW32ZI.cjs.map → chunk-ZTMYKAVU.cjs.map} +1 -1
- package/dist/{chunk-3QGS6CXD.js → chunk-ZYL4SNOR.js} +3 -3
- package/dist/{chunk-3QGS6CXD.js.map → chunk-ZYL4SNOR.js.map} +1 -1
- package/dist/components/Alert/index.d.cts +1 -1
- package/dist/components/Alert/index.d.ts +1 -1
- package/dist/components/AlertDialog/index.cjs +6 -5
- package/dist/components/AlertDialog/index.d.cts +28 -3
- package/dist/components/AlertDialog/index.d.ts +28 -3
- package/dist/components/AlertDialog/index.js +5 -4
- package/dist/components/AudioRecorder/index.d.cts +2 -2
- package/dist/components/AudioRecorder/index.d.ts +2 -2
- package/dist/components/Autocomplete/index.d.cts +8 -2
- package/dist/components/Autocomplete/index.d.ts +8 -2
- package/dist/components/Avatar/index.d.cts +1 -1
- package/dist/components/Avatar/index.d.ts +1 -1
- package/dist/components/Badge/index.d.cts +1 -1
- package/dist/components/Badge/index.d.ts +1 -1
- package/dist/components/BoardView/index.cjs +24 -0
- package/dist/components/BoardView/index.cjs.map +1 -0
- package/dist/components/BoardView/index.d.cts +41 -0
- package/dist/components/BoardView/index.d.ts +41 -0
- package/dist/components/BoardView/index.js +7 -0
- package/dist/components/BoardView/index.js.map +1 -0
- package/dist/components/Button/index.cjs +4 -3
- package/dist/components/Button/index.d.cts +2 -1
- package/dist/components/Button/index.d.ts +2 -1
- package/dist/components/Button/index.js +2 -1
- package/dist/components/CalendarView/index.cjs +23 -0
- package/dist/components/CalendarView/index.cjs.map +1 -0
- package/dist/components/CalendarView/index.d.cts +39 -0
- package/dist/components/CalendarView/index.d.ts +39 -0
- package/dist/components/CalendarView/index.js +10 -0
- package/dist/components/CalendarView/index.js.map +1 -0
- package/dist/components/Card/index.d.cts +3 -3
- package/dist/components/Card/index.d.ts +3 -3
- package/dist/components/Collapsible/index.cjs +6 -6
- package/dist/components/Collapsible/index.js +3 -3
- package/dist/components/CountryCodeDropdown/index.cjs +5 -5
- package/dist/components/CountryCodeDropdown/index.js +2 -2
- package/dist/components/CustomizableDashboard/index.cjs +10 -9
- package/dist/components/CustomizableDashboard/index.js +3 -2
- package/dist/components/Dropdown/index.cjs +10 -10
- package/dist/components/Dropdown/index.d.cts +2 -1
- package/dist/components/Dropdown/index.d.ts +2 -1
- package/dist/components/Dropdown/index.js +3 -3
- package/dist/components/FloatingWindow/index.cjs +5 -4
- package/dist/components/FloatingWindow/index.js +3 -2
- package/dist/components/GanttView/index.cjs +20 -0
- package/dist/components/GanttView/index.cjs.map +1 -0
- package/dist/components/GanttView/index.d.cts +36 -0
- package/dist/components/GanttView/index.d.ts +36 -0
- package/dist/components/GanttView/index.js +7 -0
- package/dist/components/GanttView/index.js.map +1 -0
- package/dist/components/GlossaryTooltip/index.cjs +3 -3
- package/dist/components/GlossaryTooltip/index.js +2 -2
- package/dist/components/KeyboardShortcutsOverlay/index.cjs +5 -5
- package/dist/components/KeyboardShortcutsOverlay/index.js +3 -3
- package/dist/components/ListView/index.cjs +23 -0
- package/dist/components/ListView/index.cjs.map +1 -0
- package/dist/components/ListView/index.d.cts +124 -0
- package/dist/components/ListView/index.d.ts +124 -0
- package/dist/components/ListView/index.js +10 -0
- package/dist/components/ListView/index.js.map +1 -0
- package/dist/components/Markdown/index.cjs +20 -19
- package/dist/components/Markdown/index.js +8 -7
- package/dist/components/MediaEditor/index.cjs +15 -14
- package/dist/components/MediaEditor/index.d.cts +91 -2
- package/dist/components/MediaEditor/index.d.ts +91 -2
- package/dist/components/MediaEditor/index.js +10 -9
- package/dist/components/MediaFeed/index.cjs +26 -0
- package/dist/components/MediaFeed/index.cjs.map +1 -0
- package/dist/components/MediaFeed/index.d.cts +104 -0
- package/dist/components/MediaFeed/index.d.ts +104 -0
- package/dist/components/MediaFeed/index.js +17 -0
- package/dist/components/MediaFeed/index.js.map +1 -0
- package/dist/components/MediaPlayer/index.cjs +7 -6
- package/dist/components/MediaPlayer/index.d.cts +19 -1
- package/dist/components/MediaPlayer/index.d.ts +19 -1
- package/dist/components/MediaPlayer/index.js +4 -3
- package/dist/components/MegaMenu/index.cjs +6 -5
- package/dist/components/MegaMenu/index.js +3 -2
- package/dist/components/Modal/index.cjs +10 -10
- package/dist/components/Modal/index.js +2 -2
- package/dist/components/Pagination/index.d.cts +1 -1
- package/dist/components/Pagination/index.d.ts +1 -1
- package/dist/components/PhoneInput/index.d.cts +36 -3
- package/dist/components/PhoneInput/index.d.ts +36 -3
- package/dist/components/Progress/index.d.cts +1 -1
- package/dist/components/Progress/index.d.ts +1 -1
- package/dist/components/Q/index.d.cts +2 -2
- package/dist/components/Q/index.d.ts +2 -2
- package/dist/components/QuickAction/index.d.cts +1 -1
- package/dist/components/QuickAction/index.d.ts +1 -1
- package/dist/components/RadialExplorer/index.cjs +5 -4
- package/dist/components/RadialExplorer/index.js +4 -3
- package/dist/components/RecordButton/index.d.cts +1 -1
- package/dist/components/RecordButton/index.d.ts +1 -1
- package/dist/components/RichTextEditor/index.cjs +9 -8
- package/dist/components/RichTextEditor/index.d.cts +7 -2
- package/dist/components/RichTextEditor/index.d.ts +7 -2
- package/dist/components/RichTextEditor/index.js +6 -5
- package/dist/components/ScrollArea/index.d.cts +1 -1
- package/dist/components/ScrollArea/index.d.ts +1 -1
- package/dist/components/SectionSpyNav/index.cjs +4 -3
- package/dist/components/SectionSpyNav/index.js +3 -2
- package/dist/components/Select/index.cjs +4 -4
- package/dist/components/Select/index.d.cts +1 -2
- package/dist/components/Select/index.d.ts +1 -2
- package/dist/components/Select/index.js +2 -2
- package/dist/components/Skeleton/index.d.cts +1 -1
- package/dist/components/Skeleton/index.d.ts +1 -1
- package/dist/components/Slider/index.d.cts +2 -2
- package/dist/components/Slider/index.d.ts +2 -2
- package/dist/components/SliderCalculator/index.cjs +4 -4
- package/dist/components/SliderCalculator/index.js +2 -2
- package/dist/components/SourceTip/index.cjs +3 -3
- package/dist/components/SourceTip/index.js +2 -2
- package/dist/components/Spinner/index.d.cts +2 -2
- package/dist/components/Spinner/index.d.ts +2 -2
- package/dist/components/SuperChat/index.cjs +1378 -819
- package/dist/components/SuperChat/index.cjs.map +1 -1
- package/dist/components/SuperChat/index.d.cts +35 -8
- package/dist/components/SuperChat/index.d.ts +35 -8
- package/dist/components/SuperChat/index.js +1370 -811
- package/dist/components/SuperChat/index.js.map +1 -1
- package/dist/components/SuperChat/plugins/index.cjs +6 -6
- package/dist/components/SuperChat/plugins/index.d.cts +2 -3
- package/dist/components/SuperChat/plugins/index.d.ts +2 -3
- package/dist/components/SuperChat/plugins/index.js +5 -5
- package/dist/components/Text/index.d.cts +3 -3
- package/dist/components/Text/index.d.ts +3 -3
- package/dist/components/Textarea/index.d.cts +1 -2
- package/dist/components/Textarea/index.d.ts +1 -2
- package/dist/components/ThemeProvider/index.cjs +9 -9
- package/dist/components/ThemeProvider/index.d.cts +3 -1
- package/dist/components/ThemeProvider/index.d.ts +3 -1
- package/dist/components/ThemeProvider/index.js +3 -3
- package/dist/components/Tooltip/index.cjs +3 -3
- package/dist/components/Tooltip/index.js +2 -2
- package/dist/components/TranscriptView/index.d.cts +85 -4
- package/dist/components/TranscriptView/index.d.ts +85 -4
- package/dist/components/ViewSet/index.cjs +24 -0
- package/dist/components/ViewSet/index.cjs.map +1 -0
- package/dist/components/ViewSet/index.d.cts +200 -0
- package/dist/components/ViewSet/index.d.ts +200 -0
- package/dist/components/ViewSet/index.js +15 -0
- package/dist/components/ViewSet/index.js.map +1 -0
- package/dist/components/ViewSwitcher/index.cjs +20 -0
- package/dist/components/ViewSwitcher/index.cjs.map +1 -0
- package/dist/components/ViewSwitcher/index.d.cts +4 -0
- package/dist/components/ViewSwitcher/index.d.ts +4 -0
- package/dist/components/ViewSwitcher/index.js +7 -0
- package/dist/components/ViewSwitcher/index.js.map +1 -0
- package/dist/datavis.cjs +3 -2
- package/dist/datavis.cjs.map +1 -1
- package/dist/datavis.d.cts +167 -13
- package/dist/datavis.d.ts +167 -13
- package/dist/datavis.js +2 -1
- package/dist/datavis.js.map +1 -1
- package/dist/deck.cjs +3360 -0
- package/dist/deck.cjs.map +1 -0
- package/dist/deck.d.cts +712 -0
- package/dist/deck.d.ts +712 -0
- package/dist/deck.js +3316 -0
- package/dist/deck.js.map +1 -0
- package/dist/esheet.cjs +14 -13
- package/dist/esheet.cjs.map +1 -1
- package/dist/esheet.d.cts +183 -1
- package/dist/esheet.d.ts +183 -1
- package/dist/esheet.js +11 -10
- package/dist/esheet.js.map +1 -1
- package/dist/globe.cjs +2 -2
- package/dist/globe.js +1 -1
- package/dist/hooks/index.cjs +60 -27
- package/dist/hooks/index.d.cts +590 -31
- package/dist/hooks/index.d.ts +590 -31
- package/dist/hooks/index.js +6 -5
- package/dist/icons-wBacj6BW.d.cts +142 -0
- package/dist/icons-wBacj6BW.d.ts +142 -0
- package/dist/index-DoYYWsNc.d.cts +127 -0
- package/dist/index-DoYYWsNc.d.ts +127 -0
- package/dist/index.cjs +1420 -1048
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8796 -482
- package/dist/index.d.ts +8796 -482
- package/dist/index.js +368 -232
- package/dist/index.js.map +1 -1
- package/dist/kerebron.cjs +58 -19
- package/dist/kerebron.cjs.map +1 -1
- package/dist/kerebron.css +115 -0
- package/dist/kerebron.d.cts +37 -0
- package/dist/kerebron.d.ts +37 -0
- package/dist/kerebron.js +58 -19
- package/dist/kerebron.js.map +1 -1
- package/dist/maps.cjs +160 -0
- package/dist/maps.cjs.map +1 -0
- package/dist/maps.d.cts +42 -0
- package/dist/maps.d.ts +42 -0
- package/dist/maps.js +138 -0
- package/dist/maps.js.map +1 -0
- package/dist/motion.cjs +7 -7
- package/dist/motion.d.cts +186 -2
- package/dist/motion.d.ts +186 -2
- package/dist/motion.js +2 -2
- package/dist/q.d.cts +25 -3
- package/dist/q.d.ts +25 -3
- package/dist/styles/effects.css +133 -0
- package/dist/styles/init.css +3 -0
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/templates.cjs +156 -0
- package/dist/templates.cjs.map +1 -0
- package/dist/templates.d.cts +734 -0
- package/dist/templates.d.ts +734 -0
- package/dist/templates.js +11 -0
- package/dist/templates.js.map +1 -0
- package/dist/types-Cx1FHLq2.d.cts +548 -0
- package/dist/types-Cx1FHLq2.d.ts +548 -0
- package/dist/types-DsdZvEI1.d.cts +92 -0
- package/dist/types-DsdZvEI1.d.ts +92 -0
- package/dist/utils/index.d.cts +13 -2
- package/dist/utils/index.d.ts +13 -2
- package/package.json +62 -13
- package/dist/Animated-XmH6k8pZ.d.cts +0 -188
- package/dist/Animated-XmH6k8pZ.d.ts +0 -188
- package/dist/CsvBlock-ROJCKJDP.cjs +0 -16
- package/dist/CsvBlock-UWPMTLE2.js +0 -7
- package/dist/HtmlPreviewBlock-DWFN6EUB.cjs +0 -16
- package/dist/HtmlPreviewBlock-ME5U3XNS.js +0 -7
- package/dist/MedicationEditor-Bp4NLy7y.d.cts +0 -352
- package/dist/MedicationEditor-Bp4NLy7y.d.ts +0 -352
- package/dist/MermaidBlock-2B6CPD6Y.js +0 -7
- package/dist/MermaidBlock-D2UC5M55.cjs +0 -16
- package/dist/SurveyBlock-4CD4AYMJ.cjs +0 -16
- package/dist/SurveyBlock-4DO62RBT.js +0 -7
- package/dist/chunk-22CYDCXA.js.map +0 -1
- package/dist/chunk-3T7QGLNB.js.map +0 -1
- package/dist/chunk-6HFFWEM3.cjs +0 -22
- package/dist/chunk-6HFFWEM3.cjs.map +0 -1
- package/dist/chunk-ACCAXVOG.js.map +0 -1
- package/dist/chunk-GOALNQZ2.js.map +0 -1
- package/dist/chunk-HB7C7NB5.js +0 -20
- package/dist/chunk-HB7C7NB5.js.map +0 -1
- package/dist/chunk-JHULS3EC.js.map +0 -1
- package/dist/chunk-JI244Y7C.js.map +0 -1
- package/dist/chunk-JYZW2PZS.cjs.map +0 -1
- package/dist/chunk-NV2CWBI2.cjs.map +0 -1
- package/dist/chunk-SQHMGT4W.js.map +0 -1
- package/dist/chunk-U42F3HLE.cjs.map +0 -1
- package/dist/chunk-VKELAMAZ.js.map +0 -1
- package/dist/chunk-VNYW4C4J.cjs.map +0 -1
- package/dist/chunk-WIAQQNFU.cjs.map +0 -1
- package/dist/chunk-WNAA6CLE.cjs.map +0 -1
- package/dist/chunk-WNJRS7Y7.cjs.map +0 -1
- package/dist/chunk-X4XPNTCZ.cjs.map +0 -1
- package/dist/chunk-XCP454Q6.js.map +0 -1
- package/dist/chunk-XEAT7XJG.cjs.map +0 -1
- package/dist/html-MdxqSzjD.d.cts +0 -13
- package/dist/html-MdxqSzjD.d.ts +0 -13
- package/dist/orderRows-BUJYgSc7.d.cts +0 -221
- package/dist/orderRows-BUJYgSc7.d.ts +0 -221
- package/dist/transcript-Cg7uSW-C.d.cts +0 -84
- package/dist/transcript-Cg7uSW-C.d.ts +0 -84
- package/dist/types-B97JNRNQ.d.cts +0 -251
- package/dist/types-CnPEwzlp.d.cts +0 -254
- package/dist/types-CnPEwzlp.d.ts +0 -254
- package/dist/types-gZXrfLj6.d.ts +0 -251
- package/dist/useAnchoredPosition-CKwLSQW8.d.cts +0 -76
- package/dist/useAnchoredPosition-CKwLSQW8.d.ts +0 -76
- package/dist/useTheme-B9SWu6ui.d.cts +0 -24
- package/dist/useTheme-B9SWu6ui.d.ts +0 -24
- package/dist/useTranscriptEdits-CGzlemHT.d.cts +0 -182
- package/dist/useTranscriptEdits-D32bLs0l.d.ts +0 -182
|
@@ -1,418 +1,235 @@
|
|
|
1
1
|
import { TextRenderContext } from '../../chunk-I6CY5C6A.js';
|
|
2
2
|
export { TextRenderContext, useTextRenderContext } from '../../chunk-I6CY5C6A.js';
|
|
3
|
-
import { ChatBubble, MCPToolCallDisplay, AITypingIndicator, SparklesIcon, CloseIcon } from '../../chunk-
|
|
4
|
-
import { notifyComposerMigrationOnce, ChatComposer } from '../../chunk-
|
|
5
|
-
import {
|
|
3
|
+
import { ChatBubble, MCPToolCallDisplay, AITypingIndicator, SparklesIcon, ButtonGroup, CloseIcon, JumpToBottomButton } from '../../chunk-RM2HPQIC.js';
|
|
4
|
+
import { notifyComposerMigrationOnce, ChatComposer } from '../../chunk-CRS2CQWM.js';
|
|
5
|
+
import { MediaFeed } from '../../chunk-BNH4SXJB.js';
|
|
6
|
+
import '../../chunk-RISZWWEQ.js';
|
|
7
|
+
import { MediaPlayer } from '../../chunk-2JICT4A2.js';
|
|
8
|
+
import { Dropdown, DropdownSubmenu, DropdownItem } from '../../chunk-E2PBPQGS.js';
|
|
9
|
+
import '../../chunk-VVDE4CHU.js';
|
|
6
10
|
import { Avatar } from '../../chunk-HZ4MBUC3.js';
|
|
7
11
|
import '../../chunk-IQ4KQJAO.js';
|
|
8
|
-
import '../../chunk-
|
|
12
|
+
import { useStickToBottom, useStreamEndedBelowFold } from '../../chunk-BM35CACB.js';
|
|
13
|
+
import '../../chunk-GW4RFJZ5.js';
|
|
14
|
+
import '../../chunk-ENMXHZNE.js';
|
|
9
15
|
import '../../chunk-6NZXWKUE.js';
|
|
10
16
|
import '../../chunk-3IMM2PM4.js';
|
|
17
|
+
import '../../chunk-4SMSH4OY.js';
|
|
18
|
+
import '../../chunk-T4ME7QCT.js';
|
|
11
19
|
import '../../chunk-62ZOA6PX.js';
|
|
12
20
|
import '../../chunk-WSNMQQ4P.js';
|
|
13
|
-
import '../../chunk-
|
|
21
|
+
import '../../chunk-VSQF22GL.js';
|
|
14
22
|
import '../../chunk-BKSPDTX4.js';
|
|
23
|
+
import { usePrefersReducedMotion } from '../../chunk-XDU65GLW.js';
|
|
24
|
+
import { Button } from '../../chunk-7YO7DNUV.js';
|
|
15
25
|
import { Badge } from '../../chunk-BMSG4NBH.js';
|
|
16
|
-
import '../../chunk-
|
|
26
|
+
import '../../chunk-GVM6DTR5.js';
|
|
27
|
+
import { AnimatedPresence, Animated } from '../../chunk-F4N67NAF.js';
|
|
17
28
|
import { cn } from '../../chunk-TQONQSJO.js';
|
|
18
29
|
import '../../chunk-PX6F3LHL.js';
|
|
19
|
-
import * as
|
|
30
|
+
import * as React3 from 'react';
|
|
31
|
+
import { createElement } from 'react';
|
|
32
|
+
import { Ellipsis, Check, Clipboard, Pencil, Play, ArrowLeft } from 'lucide-react';
|
|
33
|
+
import { cva } from 'class-variance-authority';
|
|
34
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
20
35
|
import Markdown, { defaultUrlTransform } from 'react-markdown';
|
|
21
36
|
import remarkGfm from 'remark-gfm';
|
|
22
37
|
import rehypeSanitize, { defaultSchema } from 'rehype-sanitize';
|
|
23
|
-
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
24
|
-
import { cva } from 'class-variance-authority';
|
|
25
|
-
import { Ellipsis, Check, Clipboard, Pencil } from 'lucide-react';
|
|
26
38
|
import { useVirtualizer } from '@tanstack/react-virtual';
|
|
27
39
|
|
|
28
|
-
function
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
function MessageMedia({
|
|
41
|
+
attachment,
|
|
42
|
+
onOpen,
|
|
43
|
+
openLabel,
|
|
44
|
+
playLabel,
|
|
45
|
+
errorLabel,
|
|
46
|
+
retryLabel,
|
|
47
|
+
launchId
|
|
48
|
+
}) {
|
|
49
|
+
const playable = attachment.kind !== "image";
|
|
50
|
+
const actionLabel = playable ? playLabel : openLabel;
|
|
51
|
+
return /* @__PURE__ */ jsxs(
|
|
52
|
+
"div",
|
|
53
|
+
{
|
|
54
|
+
"data-slot": "superchat-message-media",
|
|
55
|
+
className: "mt-3 flex w-72 max-w-full flex-col gap-2",
|
|
56
|
+
children: [
|
|
57
|
+
attachment.title && /* @__PURE__ */ jsx("p", { className: "text-sm font-medium", children: attachment.title }),
|
|
58
|
+
attachment.kind === "image" && attachment.src ? /* @__PURE__ */ jsx(
|
|
59
|
+
"img",
|
|
60
|
+
{
|
|
61
|
+
src: attachment.src,
|
|
62
|
+
alt: attachment.alt ?? attachment.title ?? "",
|
|
63
|
+
loading: "lazy",
|
|
64
|
+
className: "max-h-72 w-full rounded-lg object-contain"
|
|
65
|
+
}
|
|
66
|
+
) : (attachment.kind === "video" || attachment.kind === "audio") && attachment.src ? (
|
|
67
|
+
// An opaque themed surface: the player's semi-transparent states
|
|
68
|
+
// (error, loading) must never compose onto a colored chat bubble.
|
|
69
|
+
/* @__PURE__ */ jsx("div", { className: "bg-background overflow-hidden rounded-lg", children: /* @__PURE__ */ jsx(
|
|
70
|
+
MediaPlayer,
|
|
71
|
+
{
|
|
72
|
+
src: attachment.src,
|
|
73
|
+
kind: attachment.kind,
|
|
74
|
+
poster: attachment.poster,
|
|
75
|
+
"aria-label": attachment.alt ?? attachment.title ?? openLabel,
|
|
76
|
+
controls: !onOpen,
|
|
77
|
+
preload: "metadata",
|
|
78
|
+
labels: { error: errorLabel, retry: retryLabel },
|
|
79
|
+
className: "max-h-72"
|
|
80
|
+
}
|
|
81
|
+
) })
|
|
82
|
+
) : attachment.poster ? /* @__PURE__ */ jsx(
|
|
83
|
+
"img",
|
|
84
|
+
{
|
|
85
|
+
src: attachment.poster,
|
|
86
|
+
alt: attachment.alt ?? attachment.title ?? "",
|
|
87
|
+
loading: "lazy",
|
|
88
|
+
className: "max-h-72 w-full rounded-lg object-contain"
|
|
89
|
+
}
|
|
90
|
+
) : null,
|
|
91
|
+
attachment.caption && /* @__PURE__ */ jsx("p", { className: "text-sm", children: attachment.caption }),
|
|
92
|
+
onOpen && /* @__PURE__ */ jsx(ButtonGroup, { children: /* @__PURE__ */ jsx(
|
|
93
|
+
Button,
|
|
94
|
+
{
|
|
95
|
+
"data-media-launch-id": launchId,
|
|
96
|
+
variant: "secondary",
|
|
97
|
+
size: "sm",
|
|
98
|
+
leftIcon: playable ? /* @__PURE__ */ jsx(Play, { className: "size-4", "aria-hidden": "true" }) : void 0,
|
|
99
|
+
"aria-label": playable && attachment.title ? `${playLabel} ${attachment.title}` : actionLabel,
|
|
100
|
+
onClick: () => onOpen(playable),
|
|
101
|
+
children: actionLabel
|
|
102
|
+
}
|
|
103
|
+
) })
|
|
104
|
+
]
|
|
43
105
|
}
|
|
44
|
-
|
|
45
|
-
};
|
|
46
|
-
return (tree) => splitNode(tree);
|
|
106
|
+
);
|
|
47
107
|
}
|
|
48
|
-
function
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const withoutClass = existing.filter(
|
|
54
|
-
(a) => !(Array.isArray(a) && a[0] === "className")
|
|
55
|
-
);
|
|
56
|
-
attributes[tag] = [...withoutClass, "className"];
|
|
57
|
-
};
|
|
58
|
-
allowClass("code");
|
|
59
|
-
allowClass("pre");
|
|
60
|
-
allowClass("span");
|
|
61
|
-
allowClass("div");
|
|
62
|
-
schema.attributes = attributes;
|
|
63
|
-
return schema;
|
|
108
|
+
function formatTime(time) {
|
|
109
|
+
return new Date(time).toLocaleTimeString(void 0, {
|
|
110
|
+
hour: "numeric",
|
|
111
|
+
minute: "2-digit"
|
|
112
|
+
});
|
|
64
113
|
}
|
|
65
|
-
function
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
114
|
+
function byTime(a, b) {
|
|
115
|
+
return new Date(a.time).getTime() - new Date(b.time).getTime();
|
|
116
|
+
}
|
|
117
|
+
function lastActivityOf(c) {
|
|
118
|
+
if (c.lastActivity) return new Date(c.lastActivity).getTime();
|
|
119
|
+
const last = lastMessageByTime(c.thread);
|
|
120
|
+
return last ? new Date(last.time).getTime() : 0;
|
|
121
|
+
}
|
|
122
|
+
function escapeRegExp(value) {
|
|
123
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
124
|
+
}
|
|
125
|
+
function detectMentions(text, participants) {
|
|
126
|
+
const ids = [];
|
|
127
|
+
for (const p of participants) {
|
|
128
|
+
if (p.kind === "system") continue;
|
|
129
|
+
const token = "@" + p.name.split(" ")[0];
|
|
130
|
+
const pattern = new RegExp(
|
|
131
|
+
`(?<![\\w@])${escapeRegExp(token)}(?![\\w])`,
|
|
132
|
+
"i"
|
|
133
|
+
);
|
|
134
|
+
if (pattern.test(text)) ids.push(p.id);
|
|
71
135
|
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
))
|
|
79
|
-
|
|
136
|
+
return ids;
|
|
137
|
+
}
|
|
138
|
+
function lastMessageByTime(thread) {
|
|
139
|
+
let latest;
|
|
140
|
+
let latestTime = -Infinity;
|
|
141
|
+
for (const message of thread) {
|
|
142
|
+
const t = new Date(message.time).getTime();
|
|
143
|
+
if (t >= latestTime) {
|
|
144
|
+
latest = message;
|
|
145
|
+
latestTime = t;
|
|
80
146
|
}
|
|
81
|
-
out.attributes = baseAttrs;
|
|
82
147
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
148
|
+
return latest;
|
|
149
|
+
}
|
|
150
|
+
function parseHexColor(value) {
|
|
151
|
+
const hex = value.trim();
|
|
152
|
+
if (!/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(hex)) return null;
|
|
153
|
+
const normalized = hex.length === 4 ? "#" + [...hex.slice(1)].map((char) => char + char).join("") : hex;
|
|
154
|
+
return [1, 3, 5].map(
|
|
155
|
+
(start) => parseInt(normalized.slice(start, start + 2), 16)
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
function relativeLuminanceChannel(channel) {
|
|
159
|
+
const normalized = channel / 255;
|
|
160
|
+
return normalized <= 0.03928 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
|
|
161
|
+
}
|
|
162
|
+
function relativeLuminance(value) {
|
|
163
|
+
const rgb = parseHexColor(value);
|
|
164
|
+
if (!rgb) return null;
|
|
165
|
+
const [red, green, blue] = rgb;
|
|
166
|
+
return 0.2126 * relativeLuminanceChannel(red) + 0.7152 * relativeLuminanceChannel(green) + 0.0722 * relativeLuminanceChannel(blue);
|
|
167
|
+
}
|
|
168
|
+
function contrastRatio(foreground, background) {
|
|
169
|
+
const foregroundLuminance = relativeLuminance(foreground);
|
|
170
|
+
const backgroundLuminance = relativeLuminance(background);
|
|
171
|
+
if (foregroundLuminance === null || backgroundLuminance === null) return null;
|
|
172
|
+
const lighter = Math.max(foregroundLuminance, backgroundLuminance);
|
|
173
|
+
const darker = Math.min(foregroundLuminance, backgroundLuminance);
|
|
174
|
+
return (lighter + 0.05) / (darker + 0.05);
|
|
175
|
+
}
|
|
176
|
+
function minimumContrastRatio(value, backgrounds) {
|
|
177
|
+
const contrasts = backgrounds.map((background) => contrastRatio(value, background)).filter((contrast) => contrast !== null);
|
|
178
|
+
if (contrasts.length !== backgrounds.length) return null;
|
|
179
|
+
return Math.min(...contrasts);
|
|
180
|
+
}
|
|
181
|
+
function accessibleAccentTextColor(value) {
|
|
182
|
+
if (!value) return void 0;
|
|
183
|
+
const contrast = minimumContrastRatio(value, ["#f5f5f5", "#262626"]);
|
|
184
|
+
if (contrast === null) return value;
|
|
185
|
+
return contrast < 4.5 ? void 0 : value;
|
|
186
|
+
}
|
|
187
|
+
function ParticipantAvatar({
|
|
188
|
+
participant
|
|
189
|
+
}) {
|
|
190
|
+
const isAgent = participant?.kind === "agent";
|
|
191
|
+
const backgroundColor = participant?.color ?? (isAgent ? "var(--mieweb-primary-700, #1f2937)" : "#64748b");
|
|
192
|
+
return /* @__PURE__ */ jsx(
|
|
193
|
+
Avatar,
|
|
194
|
+
{
|
|
195
|
+
size: "xs",
|
|
196
|
+
src: participant?.avatar,
|
|
197
|
+
alt: "",
|
|
198
|
+
name: participant?.name ?? "?",
|
|
199
|
+
fallback: isAgent ? /* @__PURE__ */ jsx(SparklesIcon, { size: "sm" }) : void 0,
|
|
200
|
+
style: { backgroundColor },
|
|
201
|
+
"aria-hidden": "true",
|
|
202
|
+
className: "shrink-0"
|
|
93
203
|
}
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
for (const [k, v] of Object.entries(extra)) {
|
|
97
|
-
if (k === "tagNames" || k === "attributes" || k === "protocols") continue;
|
|
98
|
-
out[k] = v;
|
|
99
|
-
}
|
|
100
|
-
return out;
|
|
204
|
+
);
|
|
101
205
|
}
|
|
102
|
-
function
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
206
|
+
function ReferenceChip({
|
|
207
|
+
reference,
|
|
208
|
+
linkBuilder,
|
|
209
|
+
onReferenceClick
|
|
210
|
+
}) {
|
|
211
|
+
const href = linkBuilder?.(reference);
|
|
212
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
213
|
+
/* @__PURE__ */ jsx(
|
|
214
|
+
Badge,
|
|
106
215
|
{
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
),
|
|
112
|
-
target: props.target ?? "_blank",
|
|
113
|
-
rel: props.rel ?? "noopener noreferrer",
|
|
114
|
-
children
|
|
216
|
+
variant: "default",
|
|
217
|
+
size: "sm",
|
|
218
|
+
className: "rounded px-1.5 text-[10px] font-semibold tracking-wide uppercase",
|
|
219
|
+
children: reference.refType
|
|
115
220
|
}
|
|
116
221
|
),
|
|
117
|
-
|
|
118
|
-
|
|
222
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: reference.title })
|
|
223
|
+
] });
|
|
224
|
+
const className = "inline-flex max-w-full items-center gap-2 rounded-lg border border-neutral-200 bg-white px-3 py-1.5 text-sm text-neutral-700 hover:border-primary-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200";
|
|
225
|
+
if (href) {
|
|
226
|
+
return /* @__PURE__ */ jsx(
|
|
227
|
+
"a",
|
|
119
228
|
{
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
props.className
|
|
125
|
-
)
|
|
126
|
-
}
|
|
127
|
-
),
|
|
128
|
-
code: ({ node: _node, ...props }) => {
|
|
129
|
-
const isBlock = typeof props.className === "string" && props.className.includes("language-");
|
|
130
|
-
return /* @__PURE__ */ jsx(
|
|
131
|
-
"code",
|
|
132
|
-
{
|
|
133
|
-
...props,
|
|
134
|
-
className: cn(
|
|
135
|
-
!isBlock && "rounded bg-neutral-200 px-1 py-0.5 text-[0.85em] text-neutral-800 dark:bg-neutral-700 dark:text-neutral-100",
|
|
136
|
-
props.className
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
);
|
|
140
|
-
},
|
|
141
|
-
input: ({ node: _node, ...props }) => {
|
|
142
|
-
if (props.type === "checkbox") {
|
|
143
|
-
return /* @__PURE__ */ jsx(
|
|
144
|
-
"input",
|
|
145
|
-
{
|
|
146
|
-
...props,
|
|
147
|
-
"aria-label": props["aria-label"] ?? (props["aria-labelledby"] ? void 0 : "Task list item")
|
|
148
|
-
}
|
|
149
|
-
);
|
|
150
|
-
}
|
|
151
|
-
return /* @__PURE__ */ jsx("input", { ...props });
|
|
152
|
-
},
|
|
153
|
-
table: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("div", { className: "my-2 overflow-x-auto", children: /* @__PURE__ */ jsx(
|
|
154
|
-
"table",
|
|
155
|
-
{
|
|
156
|
-
...props,
|
|
157
|
-
className: cn(
|
|
158
|
-
"w-full border-collapse text-sm [&_td]:border [&_td]:border-neutral-200 [&_td]:px-2 [&_td]:py-1 dark:[&_td]:border-neutral-700 [&_th]:border [&_th]:border-neutral-200 [&_th]:px-2 [&_th]:py-1 [&_th]:text-start dark:[&_th]:border-neutral-700",
|
|
159
|
-
props.className
|
|
160
|
-
)
|
|
161
|
-
}
|
|
162
|
-
) }),
|
|
163
|
-
// Tailwind's preflight resets list markers/padding; restore them explicitly
|
|
164
|
-
// so bullets/numbers show without depending on the typography plugin.
|
|
165
|
-
ul: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("ul", { ...props, className: cn("list-disc ps-5", props.className) }),
|
|
166
|
-
ol: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("ol", { ...props, className: cn("list-decimal ps-5", props.className) }),
|
|
167
|
-
li: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("li", { ...props, className: cn("ps-1", props.className) }),
|
|
168
|
-
// Preflight also flattens headings to body size/weight; restore a sensible
|
|
169
|
-
// hierarchy without depending on the typography plugin.
|
|
170
|
-
h1: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
171
|
-
"h1",
|
|
172
|
-
{
|
|
173
|
-
...props,
|
|
174
|
-
className: cn("mt-3 mb-1 text-xl font-semibold", props.className),
|
|
175
|
-
children
|
|
176
|
-
}
|
|
177
|
-
),
|
|
178
|
-
h2: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
179
|
-
"h2",
|
|
180
|
-
{
|
|
181
|
-
...props,
|
|
182
|
-
className: cn("mt-3 mb-1 text-lg font-semibold", props.className),
|
|
183
|
-
children
|
|
184
|
-
}
|
|
185
|
-
),
|
|
186
|
-
h3: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
187
|
-
"h3",
|
|
188
|
-
{
|
|
189
|
-
...props,
|
|
190
|
-
className: cn("mt-2 mb-1 text-base font-semibold", props.className),
|
|
191
|
-
children
|
|
192
|
-
}
|
|
193
|
-
),
|
|
194
|
-
h4: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
195
|
-
"h4",
|
|
196
|
-
{
|
|
197
|
-
...props,
|
|
198
|
-
className: cn("mt-2 mb-1 text-sm font-semibold", props.className),
|
|
199
|
-
children
|
|
200
|
-
}
|
|
201
|
-
),
|
|
202
|
-
h5: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
203
|
-
"h5",
|
|
204
|
-
{
|
|
205
|
-
...props,
|
|
206
|
-
className: cn("mt-2 mb-1 text-sm font-semibold", props.className),
|
|
207
|
-
children
|
|
208
|
-
}
|
|
209
|
-
),
|
|
210
|
-
h6: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
211
|
-
"h6",
|
|
212
|
-
{
|
|
213
|
-
...props,
|
|
214
|
-
className: cn(
|
|
215
|
-
"mt-2 mb-1 text-xs font-semibold tracking-wide uppercase",
|
|
216
|
-
props.className
|
|
217
|
-
),
|
|
218
|
-
children
|
|
219
|
-
}
|
|
220
|
-
),
|
|
221
|
-
hr: ({ node: _node, ...props }) => /* @__PURE__ */ jsx(
|
|
222
|
-
"hr",
|
|
223
|
-
{
|
|
224
|
-
...props,
|
|
225
|
-
className: cn(
|
|
226
|
-
"my-2 border-neutral-300 dark:border-neutral-600",
|
|
227
|
-
props.className
|
|
228
|
-
)
|
|
229
|
-
}
|
|
230
|
-
)
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function createMarkdownRenderer(options = {}) {
|
|
234
|
-
const { plugins = [], trusted = false } = options;
|
|
235
|
-
const remarkPlugins = [
|
|
236
|
-
remarkGfm,
|
|
237
|
-
remarkPreserveLineBreaks,
|
|
238
|
-
...plugins.flatMap((p) => p.remarkPlugins ?? [])
|
|
239
|
-
];
|
|
240
|
-
const pluginRehype = plugins.flatMap(
|
|
241
|
-
(p) => p.rehypePlugins ?? []
|
|
242
|
-
);
|
|
243
|
-
const sanitizeSchema = plugins.reduce(
|
|
244
|
-
(acc, p) => mergeSanitizeSchema(acc, p.sanitizeSchema),
|
|
245
|
-
baseSanitizeSchema()
|
|
246
|
-
);
|
|
247
|
-
const rehypePlugins = trusted ? pluginRehype : [...pluginRehype, [rehypeSanitize, sanitizeSchema]];
|
|
248
|
-
const components = plugins.reduce(
|
|
249
|
-
(acc, p) => ({ ...acc, ...p.components }),
|
|
250
|
-
baseComponents()
|
|
251
|
-
);
|
|
252
|
-
const MarkdownRenderer = (text, ctx) => /* @__PURE__ */ jsx(
|
|
253
|
-
MarkdownContent,
|
|
254
|
-
{
|
|
255
|
-
text,
|
|
256
|
-
messageId: ctx.messageId,
|
|
257
|
-
streaming: ctx.streaming,
|
|
258
|
-
remarkPlugins,
|
|
259
|
-
rehypePlugins,
|
|
260
|
-
components
|
|
261
|
-
},
|
|
262
|
-
ctx.messageId
|
|
263
|
-
);
|
|
264
|
-
return MarkdownRenderer;
|
|
265
|
-
}
|
|
266
|
-
var transformUrl = (url, key, node) => {
|
|
267
|
-
if (key === "src" && node.tagName === "img" && (/^data:image\//i.test(url) || /^blob:/i.test(url))) {
|
|
268
|
-
return url;
|
|
269
|
-
}
|
|
270
|
-
return defaultUrlTransform(url);
|
|
271
|
-
};
|
|
272
|
-
var MarkdownContent = React2.memo(function MarkdownContent2({
|
|
273
|
-
text,
|
|
274
|
-
messageId,
|
|
275
|
-
streaming,
|
|
276
|
-
remarkPlugins,
|
|
277
|
-
rehypePlugins,
|
|
278
|
-
components
|
|
279
|
-
}) {
|
|
280
|
-
return /* @__PURE__ */ jsx(TextRenderContext.Provider, { value: { messageId, streaming }, children: /* @__PURE__ */ jsx(
|
|
281
|
-
Markdown,
|
|
282
|
-
{
|
|
283
|
-
remarkPlugins,
|
|
284
|
-
rehypePlugins,
|
|
285
|
-
urlTransform: transformUrl,
|
|
286
|
-
components,
|
|
287
|
-
children: text
|
|
288
|
-
}
|
|
289
|
-
) });
|
|
290
|
-
});
|
|
291
|
-
function formatTime(time) {
|
|
292
|
-
return new Date(time).toLocaleTimeString(void 0, {
|
|
293
|
-
hour: "numeric",
|
|
294
|
-
minute: "2-digit"
|
|
295
|
-
});
|
|
296
|
-
}
|
|
297
|
-
function byTime(a, b) {
|
|
298
|
-
return new Date(a.time).getTime() - new Date(b.time).getTime();
|
|
299
|
-
}
|
|
300
|
-
function lastActivityOf(c) {
|
|
301
|
-
if (c.lastActivity) return new Date(c.lastActivity).getTime();
|
|
302
|
-
const last = lastMessageByTime(c.thread);
|
|
303
|
-
return last ? new Date(last.time).getTime() : 0;
|
|
304
|
-
}
|
|
305
|
-
function escapeRegExp(value) {
|
|
306
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
307
|
-
}
|
|
308
|
-
function detectMentions(text, participants) {
|
|
309
|
-
const ids = [];
|
|
310
|
-
for (const p of participants) {
|
|
311
|
-
if (p.kind === "system") continue;
|
|
312
|
-
const token = "@" + p.name.split(" ")[0];
|
|
313
|
-
const pattern = new RegExp(
|
|
314
|
-
`(?<![\\w@])${escapeRegExp(token)}(?![\\w])`,
|
|
315
|
-
"i"
|
|
316
|
-
);
|
|
317
|
-
if (pattern.test(text)) ids.push(p.id);
|
|
318
|
-
}
|
|
319
|
-
return ids;
|
|
320
|
-
}
|
|
321
|
-
function lastMessageByTime(thread) {
|
|
322
|
-
let latest;
|
|
323
|
-
let latestTime = -Infinity;
|
|
324
|
-
for (const message of thread) {
|
|
325
|
-
const t = new Date(message.time).getTime();
|
|
326
|
-
if (t >= latestTime) {
|
|
327
|
-
latest = message;
|
|
328
|
-
latestTime = t;
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
return latest;
|
|
332
|
-
}
|
|
333
|
-
function parseHexColor(value) {
|
|
334
|
-
const hex = value.trim();
|
|
335
|
-
if (!/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.test(hex)) return null;
|
|
336
|
-
const normalized = hex.length === 4 ? "#" + [...hex.slice(1)].map((char) => char + char).join("") : hex;
|
|
337
|
-
return [1, 3, 5].map(
|
|
338
|
-
(start) => parseInt(normalized.slice(start, start + 2), 16)
|
|
339
|
-
);
|
|
340
|
-
}
|
|
341
|
-
function relativeLuminanceChannel(channel) {
|
|
342
|
-
const normalized = channel / 255;
|
|
343
|
-
return normalized <= 0.03928 ? normalized / 12.92 : ((normalized + 0.055) / 1.055) ** 2.4;
|
|
344
|
-
}
|
|
345
|
-
function relativeLuminance(value) {
|
|
346
|
-
const rgb = parseHexColor(value);
|
|
347
|
-
if (!rgb) return null;
|
|
348
|
-
const [red, green, blue] = rgb;
|
|
349
|
-
return 0.2126 * relativeLuminanceChannel(red) + 0.7152 * relativeLuminanceChannel(green) + 0.0722 * relativeLuminanceChannel(blue);
|
|
350
|
-
}
|
|
351
|
-
function contrastRatio(foreground, background) {
|
|
352
|
-
const foregroundLuminance = relativeLuminance(foreground);
|
|
353
|
-
const backgroundLuminance = relativeLuminance(background);
|
|
354
|
-
if (foregroundLuminance === null || backgroundLuminance === null) return null;
|
|
355
|
-
const lighter = Math.max(foregroundLuminance, backgroundLuminance);
|
|
356
|
-
const darker = Math.min(foregroundLuminance, backgroundLuminance);
|
|
357
|
-
return (lighter + 0.05) / (darker + 0.05);
|
|
358
|
-
}
|
|
359
|
-
function minimumContrastRatio(value, backgrounds) {
|
|
360
|
-
const contrasts = backgrounds.map((background) => contrastRatio(value, background)).filter((contrast) => contrast !== null);
|
|
361
|
-
if (contrasts.length !== backgrounds.length) return null;
|
|
362
|
-
return Math.min(...contrasts);
|
|
363
|
-
}
|
|
364
|
-
function accessibleAccentTextColor(value) {
|
|
365
|
-
if (!value) return void 0;
|
|
366
|
-
const contrast = minimumContrastRatio(value, ["#f5f5f5", "#262626"]);
|
|
367
|
-
if (contrast === null) return value;
|
|
368
|
-
return contrast < 4.5 ? void 0 : value;
|
|
369
|
-
}
|
|
370
|
-
function ParticipantAvatar({
|
|
371
|
-
participant
|
|
372
|
-
}) {
|
|
373
|
-
const isAgent = participant?.kind === "agent";
|
|
374
|
-
const backgroundColor = participant?.color ?? (isAgent ? "var(--mieweb-primary-700, #1f2937)" : "#64748b");
|
|
375
|
-
return /* @__PURE__ */ jsx(
|
|
376
|
-
Avatar,
|
|
377
|
-
{
|
|
378
|
-
size: "xs",
|
|
379
|
-
src: participant?.avatar,
|
|
380
|
-
alt: "",
|
|
381
|
-
name: participant?.name ?? "?",
|
|
382
|
-
fallback: isAgent ? /* @__PURE__ */ jsx(SparklesIcon, { size: "sm" }) : void 0,
|
|
383
|
-
style: { backgroundColor },
|
|
384
|
-
"aria-hidden": "true",
|
|
385
|
-
className: "shrink-0"
|
|
386
|
-
}
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
function ReferenceChip({
|
|
390
|
-
reference,
|
|
391
|
-
linkBuilder,
|
|
392
|
-
onReferenceClick
|
|
393
|
-
}) {
|
|
394
|
-
const href = linkBuilder?.(reference);
|
|
395
|
-
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
396
|
-
/* @__PURE__ */ jsx(
|
|
397
|
-
Badge,
|
|
398
|
-
{
|
|
399
|
-
variant: "default",
|
|
400
|
-
size: "sm",
|
|
401
|
-
className: "rounded px-1.5 text-[10px] font-semibold tracking-wide uppercase",
|
|
402
|
-
children: reference.refType
|
|
403
|
-
}
|
|
404
|
-
),
|
|
405
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: reference.title })
|
|
406
|
-
] });
|
|
407
|
-
const className = "inline-flex max-w-full items-center gap-2 rounded-lg border border-neutral-200 bg-white px-3 py-1.5 text-sm text-neutral-700 hover:border-primary-300 dark:border-neutral-700 dark:bg-neutral-800 dark:text-neutral-200";
|
|
408
|
-
if (href) {
|
|
409
|
-
return /* @__PURE__ */ jsx(
|
|
410
|
-
"a",
|
|
411
|
-
{
|
|
412
|
-
href,
|
|
413
|
-
className,
|
|
414
|
-
onClick: () => onReferenceClick?.(reference),
|
|
415
|
-
children: content
|
|
229
|
+
href,
|
|
230
|
+
className,
|
|
231
|
+
onClick: () => onReferenceClick?.(reference),
|
|
232
|
+
children: content
|
|
416
233
|
}
|
|
417
234
|
);
|
|
418
235
|
}
|
|
@@ -472,11 +289,11 @@ function useMessageCopy({
|
|
|
472
289
|
getText,
|
|
473
290
|
defaultFormat
|
|
474
291
|
}) {
|
|
475
|
-
const [copied, setCopied] =
|
|
476
|
-
const copiedTimer =
|
|
292
|
+
const [copied, setCopied] = React3.useState(false);
|
|
293
|
+
const copiedTimer = React3.useRef(
|
|
477
294
|
void 0
|
|
478
295
|
);
|
|
479
|
-
|
|
296
|
+
React3.useEffect(() => () => window.clearTimeout(copiedTimer.current), []);
|
|
480
297
|
const flash = () => {
|
|
481
298
|
setCopied(true);
|
|
482
299
|
window.clearTimeout(copiedTimer.current);
|
|
@@ -529,7 +346,7 @@ function FooterActionButton({
|
|
|
529
346
|
action,
|
|
530
347
|
isSelf
|
|
531
348
|
}) {
|
|
532
|
-
const [open, setOpen] =
|
|
349
|
+
const [open, setOpen] = React3.useState(false);
|
|
533
350
|
const onClickCapture = action.submenu ? (e) => {
|
|
534
351
|
if (e.metaKey || e.ctrlKey) {
|
|
535
352
|
e.preventDefault();
|
|
@@ -572,17 +389,13 @@ function FooterActionButton({
|
|
|
572
389
|
}
|
|
573
390
|
);
|
|
574
391
|
}
|
|
575
|
-
var MessageActionsBar =
|
|
392
|
+
var MessageActionsBar = React3.forwardRef(function MessageActionsBar2({ actions, isSelf }, ref) {
|
|
576
393
|
return /* @__PURE__ */ jsx(
|
|
577
394
|
"div",
|
|
578
395
|
{
|
|
579
396
|
ref,
|
|
580
397
|
"data-slot": "superchat-message-actions",
|
|
581
|
-
className: cn(
|
|
582
|
-
"flex items-center gap-0.5",
|
|
583
|
-
isSelf && "justify-end",
|
|
584
|
-
actionRevealClass
|
|
585
|
-
),
|
|
398
|
+
className: cn("flex flex-col items-center gap-0.5", actionRevealClass),
|
|
586
399
|
children: actions.map((action) => /* @__PURE__ */ jsx(FooterActionButton, { action, isSelf }, action.id))
|
|
587
400
|
}
|
|
588
401
|
);
|
|
@@ -592,7 +405,7 @@ function MessageOverflowMenu({
|
|
|
592
405
|
actions,
|
|
593
406
|
footerVisible
|
|
594
407
|
}) {
|
|
595
|
-
const [open, setOpen] =
|
|
408
|
+
const [open, setOpen] = React3.useState(false);
|
|
596
409
|
const select = (fn) => {
|
|
597
410
|
setOpen(false);
|
|
598
411
|
fn();
|
|
@@ -601,7 +414,7 @@ function MessageOverflowMenu({
|
|
|
601
414
|
"div",
|
|
602
415
|
{
|
|
603
416
|
className: cn(
|
|
604
|
-
"sticky bottom-2 shrink-0
|
|
417
|
+
"sticky bottom-2 mt-auto shrink-0 transition-opacity",
|
|
605
418
|
// Rich content (e.g. NITRO tables) layers internals up to z-50, so the
|
|
606
419
|
// open menu's stacking context must clear that.
|
|
607
420
|
open ? "z-[60]" : "z-10",
|
|
@@ -645,7 +458,7 @@ function MessageOverflowMenu({
|
|
|
645
458
|
}
|
|
646
459
|
);
|
|
647
460
|
}
|
|
648
|
-
var MessageRow =
|
|
461
|
+
var MessageRow = React3.memo(function MessageRow2({
|
|
649
462
|
message,
|
|
650
463
|
participant,
|
|
651
464
|
isSelf,
|
|
@@ -654,21 +467,27 @@ var MessageRow = React2.memo(function MessageRow2({
|
|
|
654
467
|
onReferenceClick,
|
|
655
468
|
editable,
|
|
656
469
|
onMessageEdited,
|
|
657
|
-
defaultCopyFormat = "rich"
|
|
470
|
+
defaultCopyFormat = "rich",
|
|
471
|
+
onOpenMedia,
|
|
472
|
+
openMediaLabel = "Open in media feed",
|
|
473
|
+
playMediaLabel = "Play",
|
|
474
|
+
mediaErrorLabel,
|
|
475
|
+
mediaRetryLabel
|
|
658
476
|
}) {
|
|
659
477
|
const streaming = message.status === "streaming";
|
|
660
|
-
const hasBody = !!message.text || (message.content?.length ?? 0) > 0;
|
|
661
|
-
const [isEditing, setIsEditing] =
|
|
662
|
-
const [draft, setDraft] =
|
|
663
|
-
const
|
|
664
|
-
const
|
|
665
|
-
const
|
|
478
|
+
const hasBody = !!message.text || (message.content?.length ?? 0) > 0 || (message.media?.length ?? 0) > 0;
|
|
479
|
+
const [isEditing, setIsEditing] = React3.useState(false);
|
|
480
|
+
const [draft, setDraft] = React3.useState(message.text ?? "");
|
|
481
|
+
const [editMinWidth, setEditMinWidth] = React3.useState();
|
|
482
|
+
const editRef = React3.useRef(null);
|
|
483
|
+
const bubbleRef = React3.useRef(null);
|
|
484
|
+
const autosize = React3.useCallback(() => {
|
|
666
485
|
const el = editRef.current;
|
|
667
486
|
if (!el) return;
|
|
668
487
|
el.style.height = "auto";
|
|
669
488
|
el.style.height = `${el.scrollHeight}px`;
|
|
670
489
|
}, []);
|
|
671
|
-
|
|
490
|
+
React3.useEffect(() => {
|
|
672
491
|
if (!isEditing) return;
|
|
673
492
|
const el = editRef.current;
|
|
674
493
|
if (!el) return;
|
|
@@ -683,337 +502,662 @@ var MessageRow = React2.memo(function MessageRow2({
|
|
|
683
502
|
${block.text}
|
|
684
503
|
\`\`\``;
|
|
685
504
|
}
|
|
686
|
-
if ((block.type === "text" || block.type === "thinking") && block.text) {
|
|
687
|
-
return block.text;
|
|
505
|
+
if ((block.type === "text" || block.type === "thinking") && block.text) {
|
|
506
|
+
return block.text;
|
|
507
|
+
}
|
|
508
|
+
return "";
|
|
509
|
+
}).filter(Boolean).join("\n\n") ?? "";
|
|
510
|
+
const canCopy = !isEditing && (!!message.content?.length || typeof message.text === "string" && message.text.length > 0);
|
|
511
|
+
const showEditAction = canEdit && !isEditing;
|
|
512
|
+
const actionCount = (canCopy ? 1 : 0) + (showEditAction ? 1 : 0);
|
|
513
|
+
const hasActions = actionCount > 0;
|
|
514
|
+
const collapseToMenu = actionCount > 1;
|
|
515
|
+
const copy = useMessageCopy({
|
|
516
|
+
markdown: markdownSource,
|
|
517
|
+
getHtml: () => bubbleRef.current?.innerHTML ?? "",
|
|
518
|
+
getText: () => bubbleRef.current?.textContent ?? "",
|
|
519
|
+
defaultFormat: defaultCopyFormat
|
|
520
|
+
});
|
|
521
|
+
const actionsBarRef = React3.useRef(null);
|
|
522
|
+
const [footerVisible, setFooterVisible] = React3.useState(true);
|
|
523
|
+
React3.useEffect(() => {
|
|
524
|
+
const el = actionsBarRef.current;
|
|
525
|
+
if (!el || typeof globalThis.IntersectionObserver === "undefined") return;
|
|
526
|
+
const observer = new globalThis.IntersectionObserver(([entry]) => {
|
|
527
|
+
setFooterVisible(entry?.isIntersecting ?? false);
|
|
528
|
+
});
|
|
529
|
+
observer.observe(el);
|
|
530
|
+
return () => observer.disconnect();
|
|
531
|
+
}, [hasActions, collapseToMenu]);
|
|
532
|
+
if (message.type === "system") {
|
|
533
|
+
return /* @__PURE__ */ jsx(
|
|
534
|
+
"div",
|
|
535
|
+
{
|
|
536
|
+
"data-slot": "superchat-system-message",
|
|
537
|
+
role: "status",
|
|
538
|
+
className: "my-1 text-center text-xs text-neutral-500 dark:text-neutral-400",
|
|
539
|
+
children: message.text
|
|
540
|
+
}
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
if (message.type === "ref" && message.ref) {
|
|
544
|
+
return /* @__PURE__ */ jsx(
|
|
545
|
+
"div",
|
|
546
|
+
{
|
|
547
|
+
"data-slot": "superchat-reference",
|
|
548
|
+
className: cn("flex", isSelf && "justify-end"),
|
|
549
|
+
children: /* @__PURE__ */ jsx(
|
|
550
|
+
ReferenceChip,
|
|
551
|
+
{
|
|
552
|
+
reference: message.ref,
|
|
553
|
+
linkBuilder,
|
|
554
|
+
onReferenceClick
|
|
555
|
+
}
|
|
556
|
+
)
|
|
557
|
+
}
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
const accent = participant?.color;
|
|
561
|
+
const accentTextColor = accessibleAccentTextColor(accent);
|
|
562
|
+
const authorName = participant?.name ?? "Unknown";
|
|
563
|
+
const startEdit = () => {
|
|
564
|
+
const el = bubbleRef.current;
|
|
565
|
+
if (el) {
|
|
566
|
+
const cs = getComputedStyle(el);
|
|
567
|
+
const contentWidth = el.clientWidth - parseFloat(cs.paddingLeft) - parseFloat(cs.paddingRight);
|
|
568
|
+
setEditMinWidth(contentWidth > 0 ? contentWidth : void 0);
|
|
569
|
+
}
|
|
570
|
+
setDraft(message.text ?? "");
|
|
571
|
+
setIsEditing(true);
|
|
572
|
+
};
|
|
573
|
+
const cancelEdit = () => setIsEditing(false);
|
|
574
|
+
const saveEdit = () => {
|
|
575
|
+
const next = draft.trim();
|
|
576
|
+
if (next && next !== message.text) onMessageEdited?.(message.id, next);
|
|
577
|
+
setIsEditing(false);
|
|
578
|
+
};
|
|
579
|
+
const handleEditPaste = (e) => {
|
|
580
|
+
const files = Array.from(e.clipboardData.items).filter((item) => item.kind === "file" && item.type.startsWith("image/")).map((item) => item.getAsFile()).filter((f) => f !== null);
|
|
581
|
+
if (files.length === 0) return;
|
|
582
|
+
e.preventDefault();
|
|
583
|
+
const el = e.currentTarget;
|
|
584
|
+
const start = el.selectionStart ?? draft.length;
|
|
585
|
+
const end = el.selectionEnd ?? draft.length;
|
|
586
|
+
Promise.all(
|
|
587
|
+
files.map(
|
|
588
|
+
(file, i) => new Promise((resolve) => {
|
|
589
|
+
const reader = new window.FileReader();
|
|
590
|
+
reader.onload = () => {
|
|
591
|
+
const dataUrl = typeof reader.result === "string" ? reader.result : "";
|
|
592
|
+
const name = file.name || `pasted-image-${i + 1}.png`;
|
|
593
|
+
resolve(dataUrl ? `` : "");
|
|
594
|
+
};
|
|
595
|
+
reader.readAsDataURL(file);
|
|
596
|
+
})
|
|
597
|
+
)
|
|
598
|
+
).then((snippets) => {
|
|
599
|
+
const insert = snippets.filter(Boolean).join("\n");
|
|
600
|
+
if (!insert) return;
|
|
601
|
+
el.focus();
|
|
602
|
+
el.setSelectionRange(start, end);
|
|
603
|
+
const text = `${insert}
|
|
604
|
+
`;
|
|
605
|
+
const inserted = typeof document !== "undefined" && typeof document.execCommand === "function" && document.execCommand("insertText", false, text);
|
|
606
|
+
if (!inserted) {
|
|
607
|
+
setDraft((prev) => `${prev.slice(0, start)}${text}${prev.slice(end)}`);
|
|
608
|
+
}
|
|
609
|
+
requestAnimationFrame(autosize);
|
|
610
|
+
});
|
|
611
|
+
};
|
|
612
|
+
const actions = [
|
|
613
|
+
...canCopy ? [
|
|
614
|
+
{
|
|
615
|
+
id: "copy",
|
|
616
|
+
label: "Copy message",
|
|
617
|
+
title: "Copy message (\u2318/Ctrl-click: default format)",
|
|
618
|
+
icon: copy.copied ? /* @__PURE__ */ jsx(Check, { size: 14, "aria-hidden": "true" }) : /* @__PURE__ */ jsx(Clipboard, { size: 14, "aria-hidden": "true" }),
|
|
619
|
+
onSelect: copy.copyDefault,
|
|
620
|
+
submenu: {
|
|
621
|
+
label: "Copy as",
|
|
622
|
+
items: [
|
|
623
|
+
{
|
|
624
|
+
id: "copy-rich",
|
|
625
|
+
label: "Copy as rich text",
|
|
626
|
+
description: "Rich text + Markdown",
|
|
627
|
+
onSelect: copy.copyRich
|
|
628
|
+
},
|
|
629
|
+
{
|
|
630
|
+
id: "copy-markdown",
|
|
631
|
+
label: "Copy as Markdown",
|
|
632
|
+
onSelect: copy.copyMarkdown
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
id: "copy-plain",
|
|
636
|
+
label: "Copy as plain text",
|
|
637
|
+
onSelect: copy.copyPlain
|
|
638
|
+
}
|
|
639
|
+
]
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
] : [],
|
|
643
|
+
...showEditAction ? [
|
|
644
|
+
{
|
|
645
|
+
id: "edit",
|
|
646
|
+
label: "Edit message",
|
|
647
|
+
icon: /* @__PURE__ */ jsx(Pencil, { size: 14, "aria-hidden": "true" }),
|
|
648
|
+
onSelect: startEdit
|
|
649
|
+
}
|
|
650
|
+
] : []
|
|
651
|
+
];
|
|
652
|
+
return /* @__PURE__ */ jsxs(
|
|
653
|
+
"div",
|
|
654
|
+
{
|
|
655
|
+
"data-slot": "superchat-message",
|
|
656
|
+
role: "article",
|
|
657
|
+
"aria-label": `${authorName}, ${formatTime(message.time)}`,
|
|
658
|
+
className: cn(
|
|
659
|
+
"group flex gap-2",
|
|
660
|
+
isSelf ? "flex-row-reverse" : "flex-row"
|
|
661
|
+
),
|
|
662
|
+
children: [
|
|
663
|
+
/* @__PURE__ */ jsxs(
|
|
664
|
+
"div",
|
|
665
|
+
{
|
|
666
|
+
"data-slot": "superchat-message-gutter",
|
|
667
|
+
className: "flex shrink-0 flex-col items-center gap-1",
|
|
668
|
+
children: [
|
|
669
|
+
/* @__PURE__ */ jsx(ParticipantAvatar, { participant }),
|
|
670
|
+
hasActions && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
671
|
+
/* @__PURE__ */ jsx(
|
|
672
|
+
MessageOverflowMenu,
|
|
673
|
+
{
|
|
674
|
+
isSelf,
|
|
675
|
+
actions,
|
|
676
|
+
footerVisible: collapseToMenu ? false : footerVisible
|
|
677
|
+
}
|
|
678
|
+
),
|
|
679
|
+
!collapseToMenu && /* @__PURE__ */ jsx(
|
|
680
|
+
MessageActionsBar,
|
|
681
|
+
{
|
|
682
|
+
ref: actionsBarRef,
|
|
683
|
+
actions,
|
|
684
|
+
isSelf
|
|
685
|
+
}
|
|
686
|
+
)
|
|
687
|
+
] })
|
|
688
|
+
]
|
|
689
|
+
}
|
|
690
|
+
),
|
|
691
|
+
/* @__PURE__ */ jsxs(
|
|
692
|
+
"div",
|
|
693
|
+
{
|
|
694
|
+
className: cn(
|
|
695
|
+
"flex min-w-0 flex-1 flex-col gap-1",
|
|
696
|
+
isSelf && "items-end"
|
|
697
|
+
),
|
|
698
|
+
children: [
|
|
699
|
+
/* @__PURE__ */ jsxs(
|
|
700
|
+
"div",
|
|
701
|
+
{
|
|
702
|
+
"data-slot": "superchat-message-meta",
|
|
703
|
+
className: "flex items-baseline gap-2",
|
|
704
|
+
children: [
|
|
705
|
+
/* @__PURE__ */ jsx(
|
|
706
|
+
"span",
|
|
707
|
+
{
|
|
708
|
+
className: "text-xs font-medium",
|
|
709
|
+
style: accentTextColor ? { color: accentTextColor } : void 0,
|
|
710
|
+
children: authorName
|
|
711
|
+
}
|
|
712
|
+
),
|
|
713
|
+
participant?.role && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-neutral-500 dark:text-neutral-400", children: participant.role }),
|
|
714
|
+
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-neutral-500 dark:text-neutral-400", children: formatTime(message.time) }),
|
|
715
|
+
message.editedAt && /* @__PURE__ */ jsx(
|
|
716
|
+
"span",
|
|
717
|
+
{
|
|
718
|
+
"data-slot": "superchat-edited-indicator",
|
|
719
|
+
className: "text-[10px] text-neutral-500 dark:text-neutral-400",
|
|
720
|
+
title: `Edited ${formatTime(message.editedAt)}`,
|
|
721
|
+
children: "(edited)"
|
|
722
|
+
}
|
|
723
|
+
)
|
|
724
|
+
]
|
|
725
|
+
}
|
|
726
|
+
),
|
|
727
|
+
/* @__PURE__ */ jsx(
|
|
728
|
+
"div",
|
|
729
|
+
{
|
|
730
|
+
className: cn(
|
|
731
|
+
"flex w-full items-center gap-1",
|
|
732
|
+
isSelf ? "flex-row-reverse" : "flex-row"
|
|
733
|
+
),
|
|
734
|
+
children: /* @__PURE__ */ jsx(
|
|
735
|
+
ChatBubble,
|
|
736
|
+
{
|
|
737
|
+
ref: bubbleRef,
|
|
738
|
+
"data-slot": "superchat-bubble",
|
|
739
|
+
variant: isSelf ? "user" : "assistant",
|
|
740
|
+
hasError: message.status === "error",
|
|
741
|
+
className: "text-sm has-[[data-slot=superchat-nitro-table]]:w-full has-[[data-slot=superchat-nitro-table]]:max-w-full",
|
|
742
|
+
children: isEditing ? /* @__PURE__ */ jsxs(
|
|
743
|
+
"div",
|
|
744
|
+
{
|
|
745
|
+
"data-slot": "superchat-message-editor",
|
|
746
|
+
className: "flex w-80 max-w-full flex-col gap-2",
|
|
747
|
+
style: editMinWidth ? { minWidth: editMinWidth } : void 0,
|
|
748
|
+
children: [
|
|
749
|
+
/* @__PURE__ */ jsx(
|
|
750
|
+
"textarea",
|
|
751
|
+
{
|
|
752
|
+
value: draft,
|
|
753
|
+
ref: editRef,
|
|
754
|
+
rows: 2,
|
|
755
|
+
onChange: (e) => {
|
|
756
|
+
setDraft(e.target.value);
|
|
757
|
+
autosize();
|
|
758
|
+
},
|
|
759
|
+
onPaste: handleEditPaste,
|
|
760
|
+
onKeyDown: (e) => {
|
|
761
|
+
if (e.key === "Enter" && !e.shiftKey) {
|
|
762
|
+
e.preventDefault();
|
|
763
|
+
saveEdit();
|
|
764
|
+
} else if (e.key === "Escape") {
|
|
765
|
+
e.preventDefault();
|
|
766
|
+
cancelEdit();
|
|
767
|
+
}
|
|
768
|
+
},
|
|
769
|
+
"aria-label": "Edit message",
|
|
770
|
+
className: "focus:ring-primary-500 max-h-60 min-h-16 w-full resize-none rounded-lg border border-neutral-300 bg-white px-3 py-2 text-sm text-neutral-900 focus:ring-1 focus:outline-none dark:border-neutral-600 dark:bg-neutral-900 dark:text-white"
|
|
771
|
+
}
|
|
772
|
+
),
|
|
773
|
+
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
774
|
+
/* @__PURE__ */ jsx(
|
|
775
|
+
"button",
|
|
776
|
+
{
|
|
777
|
+
type: "button",
|
|
778
|
+
onClick: cancelEdit,
|
|
779
|
+
className: "rounded-md px-2.5 py-1 text-xs font-medium text-neutral-200 hover:bg-white/10",
|
|
780
|
+
children: "Cancel"
|
|
781
|
+
}
|
|
782
|
+
),
|
|
783
|
+
/* @__PURE__ */ jsx(
|
|
784
|
+
"button",
|
|
785
|
+
{
|
|
786
|
+
type: "button",
|
|
787
|
+
onClick: saveEdit,
|
|
788
|
+
disabled: !draft.trim() || draft.trim() === message.text,
|
|
789
|
+
className: "rounded-md bg-white px-2.5 py-1 text-xs font-medium text-neutral-900 hover:bg-neutral-100 disabled:opacity-40",
|
|
790
|
+
children: "Save"
|
|
791
|
+
}
|
|
792
|
+
)
|
|
793
|
+
] })
|
|
794
|
+
]
|
|
795
|
+
}
|
|
796
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
797
|
+
message.content?.map((block, i) => {
|
|
798
|
+
if (block.type === "tool_use" && block.toolCall) {
|
|
799
|
+
return /* @__PURE__ */ jsx(MCPToolCallDisplay, { toolCall: block.toolCall }, i);
|
|
800
|
+
}
|
|
801
|
+
if ((block.type === "text" || block.type === "thinking") && block.text) {
|
|
802
|
+
return /* @__PURE__ */ jsx(
|
|
803
|
+
"div",
|
|
804
|
+
{
|
|
805
|
+
className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word",
|
|
806
|
+
children: renderText(block.text, {
|
|
807
|
+
messageId: message.id,
|
|
808
|
+
streaming,
|
|
809
|
+
role: participant?.kind === "human" ? "user" : "assistant"
|
|
810
|
+
})
|
|
811
|
+
},
|
|
812
|
+
i
|
|
813
|
+
);
|
|
814
|
+
}
|
|
815
|
+
if (block.type === "code" && block.text) {
|
|
816
|
+
const fenced = `\`\`\`${block.language ?? ""}
|
|
817
|
+
${block.text}
|
|
818
|
+
\`\`\``;
|
|
819
|
+
return /* @__PURE__ */ jsx(
|
|
820
|
+
"div",
|
|
821
|
+
{
|
|
822
|
+
className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word",
|
|
823
|
+
children: renderText(fenced, {
|
|
824
|
+
messageId: message.id,
|
|
825
|
+
streaming,
|
|
826
|
+
role: participant?.kind === "human" ? "user" : "assistant"
|
|
827
|
+
})
|
|
828
|
+
},
|
|
829
|
+
i
|
|
830
|
+
);
|
|
831
|
+
}
|
|
832
|
+
return null;
|
|
833
|
+
}),
|
|
834
|
+
message.text && /* @__PURE__ */ jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word", children: renderText(message.text, {
|
|
835
|
+
messageId: message.id,
|
|
836
|
+
streaming,
|
|
837
|
+
role: participant?.kind === "human" ? "user" : "assistant"
|
|
838
|
+
}) }),
|
|
839
|
+
message.media?.map((attachment) => /* @__PURE__ */ jsx(
|
|
840
|
+
MessageMedia,
|
|
841
|
+
{
|
|
842
|
+
attachment,
|
|
843
|
+
openLabel: openMediaLabel,
|
|
844
|
+
playLabel: playMediaLabel,
|
|
845
|
+
errorLabel: mediaErrorLabel,
|
|
846
|
+
retryLabel: mediaRetryLabel,
|
|
847
|
+
launchId: JSON.stringify([message.id, attachment.id]),
|
|
848
|
+
onOpen: onOpenMedia ? (play) => onOpenMedia(message.id, attachment.id, play) : void 0
|
|
849
|
+
},
|
|
850
|
+
attachment.id
|
|
851
|
+
)),
|
|
852
|
+
streaming && !hasBody && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(AITypingIndicator, {}) })
|
|
853
|
+
] })
|
|
854
|
+
}
|
|
855
|
+
)
|
|
856
|
+
}
|
|
857
|
+
)
|
|
858
|
+
]
|
|
859
|
+
}
|
|
860
|
+
)
|
|
861
|
+
]
|
|
862
|
+
}
|
|
863
|
+
);
|
|
864
|
+
});
|
|
865
|
+
var sidebarItem = cva(
|
|
866
|
+
"flex w-full items-center gap-2 rounded-lg px-3 py-2 text-start text-sm transition-colors",
|
|
867
|
+
{
|
|
868
|
+
variants: {
|
|
869
|
+
active: {
|
|
870
|
+
true: "bg-primary-100 text-primary-900 dark:bg-primary-900/40 dark:text-primary-100",
|
|
871
|
+
false: "text-neutral-700 hover:bg-neutral-100 dark:text-neutral-200 dark:hover:bg-neutral-800"
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
defaultVariants: { active: false }
|
|
875
|
+
}
|
|
876
|
+
);
|
|
877
|
+
|
|
878
|
+
// src/components/SuperChat/media.ts
|
|
879
|
+
function getConversationMediaItems(conversation) {
|
|
880
|
+
const participants = new Map(
|
|
881
|
+
conversation.participants.map((participant) => [
|
|
882
|
+
participant.id,
|
|
883
|
+
participant
|
|
884
|
+
])
|
|
885
|
+
);
|
|
886
|
+
return [...conversation.thread].sort(byTime).flatMap(
|
|
887
|
+
(message) => (message.media ?? []).map((attachment) => ({
|
|
888
|
+
// Tuple encoding prevents collisions when ids themselves contain a
|
|
889
|
+
// delimiter. Including the conversation keeps selection scoped to it.
|
|
890
|
+
id: JSON.stringify([conversation.id, message.id, attachment.id]),
|
|
891
|
+
conversationId: conversation.id,
|
|
892
|
+
message,
|
|
893
|
+
attachment,
|
|
894
|
+
participant: participants.get(message.participantId)
|
|
895
|
+
}))
|
|
896
|
+
);
|
|
897
|
+
}
|
|
898
|
+
function remarkPreserveLineBreaks() {
|
|
899
|
+
const splitNode = (node) => {
|
|
900
|
+
if (!node.children) return;
|
|
901
|
+
const next = [];
|
|
902
|
+
for (const child of node.children) {
|
|
903
|
+
if (child.type === "text" && child.value && child.value.includes("\n")) {
|
|
904
|
+
const segments = child.value.split("\n");
|
|
905
|
+
segments.forEach((segment, i) => {
|
|
906
|
+
if (i > 0) next.push({ type: "break" });
|
|
907
|
+
if (segment) next.push({ type: "text", value: segment });
|
|
908
|
+
});
|
|
909
|
+
} else {
|
|
910
|
+
splitNode(child);
|
|
911
|
+
next.push(child);
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
node.children = next;
|
|
915
|
+
};
|
|
916
|
+
return (tree) => splitNode(tree);
|
|
917
|
+
}
|
|
918
|
+
function baseSanitizeSchema() {
|
|
919
|
+
const schema = JSON.parse(JSON.stringify(defaultSchema));
|
|
920
|
+
const attributes = schema.attributes ?? {};
|
|
921
|
+
const allowClass = (tag) => {
|
|
922
|
+
const existing = attributes[tag] ?? [];
|
|
923
|
+
const withoutClass = existing.filter(
|
|
924
|
+
(a) => !(Array.isArray(a) && a[0] === "className")
|
|
925
|
+
);
|
|
926
|
+
attributes[tag] = [...withoutClass, "className"];
|
|
927
|
+
};
|
|
928
|
+
allowClass("code");
|
|
929
|
+
allowClass("pre");
|
|
930
|
+
allowClass("span");
|
|
931
|
+
allowClass("div");
|
|
932
|
+
schema.attributes = attributes;
|
|
933
|
+
return schema;
|
|
934
|
+
}
|
|
935
|
+
function mergeSanitizeSchema(base, extra) {
|
|
936
|
+
if (!extra) return base;
|
|
937
|
+
const out = { ...base };
|
|
938
|
+
if (Array.isArray(extra.tagNames)) {
|
|
939
|
+
const a = base.tagNames ?? [];
|
|
940
|
+
out.tagNames = Array.from(/* @__PURE__ */ new Set([...a, ...extra.tagNames]));
|
|
941
|
+
}
|
|
942
|
+
if (extra.attributes && typeof extra.attributes === "object") {
|
|
943
|
+
const baseAttrs = {
|
|
944
|
+
...base.attributes ?? {}
|
|
945
|
+
};
|
|
946
|
+
for (const [tag, attrs] of Object.entries(
|
|
947
|
+
extra.attributes
|
|
948
|
+
)) {
|
|
949
|
+
baseAttrs[tag] = [...baseAttrs[tag] ?? [], ...attrs];
|
|
950
|
+
}
|
|
951
|
+
out.attributes = baseAttrs;
|
|
952
|
+
}
|
|
953
|
+
if (extra.protocols && typeof extra.protocols === "object") {
|
|
954
|
+
const baseProtocols = {
|
|
955
|
+
...base.protocols ?? {}
|
|
956
|
+
};
|
|
957
|
+
for (const [attr, protocols] of Object.entries(
|
|
958
|
+
extra.protocols
|
|
959
|
+
)) {
|
|
960
|
+
baseProtocols[attr] = Array.from(
|
|
961
|
+
/* @__PURE__ */ new Set([...baseProtocols[attr] ?? [], ...protocols])
|
|
962
|
+
);
|
|
688
963
|
}
|
|
689
|
-
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
React2.useEffect(() => {
|
|
702
|
-
const el = actionsBarRef.current;
|
|
703
|
-
if (!el || typeof globalThis.IntersectionObserver === "undefined") return;
|
|
704
|
-
const observer = new globalThis.IntersectionObserver(([entry]) => {
|
|
705
|
-
setFooterVisible(entry?.isIntersecting ?? false);
|
|
706
|
-
});
|
|
707
|
-
observer.observe(el);
|
|
708
|
-
return () => observer.disconnect();
|
|
709
|
-
}, [hasActions]);
|
|
710
|
-
if (message.type === "system") {
|
|
711
|
-
return /* @__PURE__ */ jsx(
|
|
712
|
-
"div",
|
|
964
|
+
out.protocols = baseProtocols;
|
|
965
|
+
}
|
|
966
|
+
for (const [k, v] of Object.entries(extra)) {
|
|
967
|
+
if (k === "tagNames" || k === "attributes" || k === "protocols") continue;
|
|
968
|
+
out[k] = v;
|
|
969
|
+
}
|
|
970
|
+
return out;
|
|
971
|
+
}
|
|
972
|
+
function baseComponents() {
|
|
973
|
+
return {
|
|
974
|
+
a: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
975
|
+
"a",
|
|
713
976
|
{
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
977
|
+
...props,
|
|
978
|
+
className: cn(
|
|
979
|
+
"text-primary-800 hover:text-primary-900 dark:text-primary-300 underline underline-offset-2",
|
|
980
|
+
props.className
|
|
981
|
+
),
|
|
982
|
+
target: props.target ?? "_blank",
|
|
983
|
+
rel: props.rel ?? "noopener noreferrer",
|
|
984
|
+
children
|
|
718
985
|
}
|
|
719
|
-
)
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
return /* @__PURE__ */ jsx(
|
|
723
|
-
"div",
|
|
986
|
+
),
|
|
987
|
+
pre: ({ node: _node, ...props }) => /* @__PURE__ */ jsx(
|
|
988
|
+
"pre",
|
|
724
989
|
{
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
990
|
+
...props,
|
|
991
|
+
tabIndex: 0,
|
|
992
|
+
className: cn(
|
|
993
|
+
"overflow-x-auto rounded-lg bg-neutral-900 p-3 text-sm text-neutral-100 dark:bg-neutral-950",
|
|
994
|
+
props.className
|
|
995
|
+
)
|
|
996
|
+
}
|
|
997
|
+
),
|
|
998
|
+
code: ({ node: _node, ...props }) => {
|
|
999
|
+
const isBlock = typeof props.className === "string" && props.className.includes("language-");
|
|
1000
|
+
return /* @__PURE__ */ jsx(
|
|
1001
|
+
"code",
|
|
1002
|
+
{
|
|
1003
|
+
...props,
|
|
1004
|
+
className: cn(
|
|
1005
|
+
!isBlock && "rounded bg-neutral-200 px-1 py-0.5 text-[0.85em] text-neutral-800 dark:bg-neutral-700 dark:text-neutral-100",
|
|
1006
|
+
props.className
|
|
1007
|
+
)
|
|
1008
|
+
}
|
|
1009
|
+
);
|
|
1010
|
+
},
|
|
1011
|
+
input: ({ node: _node, ...props }) => {
|
|
1012
|
+
if (props.type === "checkbox") {
|
|
1013
|
+
return /* @__PURE__ */ jsx(
|
|
1014
|
+
"input",
|
|
729
1015
|
{
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
onReferenceClick
|
|
1016
|
+
...props,
|
|
1017
|
+
"aria-label": props["aria-label"] ?? (props["aria-labelledby"] ? void 0 : "Task list item")
|
|
733
1018
|
}
|
|
1019
|
+
);
|
|
1020
|
+
}
|
|
1021
|
+
return /* @__PURE__ */ jsx("input", { ...props });
|
|
1022
|
+
},
|
|
1023
|
+
table: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("div", { className: "my-2 overflow-x-auto", children: /* @__PURE__ */ jsx(
|
|
1024
|
+
"table",
|
|
1025
|
+
{
|
|
1026
|
+
...props,
|
|
1027
|
+
className: cn(
|
|
1028
|
+
"w-full border-collapse text-sm [&_td]:border [&_td]:border-neutral-200 [&_td]:px-2 [&_td]:py-1 dark:[&_td]:border-neutral-700 [&_th]:border [&_th]:border-neutral-200 [&_th]:px-2 [&_th]:py-1 [&_th]:text-start dark:[&_th]:border-neutral-700",
|
|
1029
|
+
props.className
|
|
734
1030
|
)
|
|
735
1031
|
}
|
|
736
|
-
)
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
};
|
|
751
|
-
const handleEditPaste = (e) => {
|
|
752
|
-
const files = Array.from(e.clipboardData.items).filter((item) => item.kind === "file" && item.type.startsWith("image/")).map((item) => item.getAsFile()).filter((f) => f !== null);
|
|
753
|
-
if (files.length === 0) return;
|
|
754
|
-
e.preventDefault();
|
|
755
|
-
const el = e.currentTarget;
|
|
756
|
-
const start = el.selectionStart ?? draft.length;
|
|
757
|
-
const end = el.selectionEnd ?? draft.length;
|
|
758
|
-
Promise.all(
|
|
759
|
-
files.map(
|
|
760
|
-
(file, i) => new Promise((resolve) => {
|
|
761
|
-
const reader = new window.FileReader();
|
|
762
|
-
reader.onload = () => {
|
|
763
|
-
const dataUrl = typeof reader.result === "string" ? reader.result : "";
|
|
764
|
-
const name = file.name || `pasted-image-${i + 1}.png`;
|
|
765
|
-
resolve(dataUrl ? `` : "");
|
|
766
|
-
};
|
|
767
|
-
reader.readAsDataURL(file);
|
|
768
|
-
})
|
|
769
|
-
)
|
|
770
|
-
).then((snippets) => {
|
|
771
|
-
const insert = snippets.filter(Boolean).join("\n");
|
|
772
|
-
if (!insert) return;
|
|
773
|
-
el.focus();
|
|
774
|
-
el.setSelectionRange(start, end);
|
|
775
|
-
const text = `${insert}
|
|
776
|
-
`;
|
|
777
|
-
const inserted = typeof document !== "undefined" && typeof document.execCommand === "function" && document.execCommand("insertText", false, text);
|
|
778
|
-
if (!inserted) {
|
|
779
|
-
setDraft((prev) => `${prev.slice(0, start)}${text}${prev.slice(end)}`);
|
|
1032
|
+
) }),
|
|
1033
|
+
// Tailwind's preflight resets list markers/padding; restore them explicitly
|
|
1034
|
+
// so bullets/numbers show without depending on the typography plugin.
|
|
1035
|
+
ul: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("ul", { ...props, className: cn("list-disc ps-5", props.className) }),
|
|
1036
|
+
ol: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("ol", { ...props, className: cn("list-decimal ps-5", props.className) }),
|
|
1037
|
+
li: ({ node: _node, ...props }) => /* @__PURE__ */ jsx("li", { ...props, className: cn("ps-1", props.className) }),
|
|
1038
|
+
// Preflight also flattens headings to body size/weight; restore a sensible
|
|
1039
|
+
// hierarchy without depending on the typography plugin.
|
|
1040
|
+
h1: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
1041
|
+
"h1",
|
|
1042
|
+
{
|
|
1043
|
+
...props,
|
|
1044
|
+
className: cn("mt-3 mb-1 text-xl font-semibold", props.className),
|
|
1045
|
+
children
|
|
780
1046
|
}
|
|
781
|
-
|
|
782
|
-
})
|
|
783
|
-
|
|
784
|
-
const actions = [
|
|
785
|
-
...canCopy ? [
|
|
1047
|
+
),
|
|
1048
|
+
h2: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
1049
|
+
"h2",
|
|
786
1050
|
{
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
{
|
|
807
|
-
id: "copy-plain",
|
|
808
|
-
label: "Copy as plain text",
|
|
809
|
-
onSelect: copy.copyPlain
|
|
810
|
-
}
|
|
811
|
-
]
|
|
812
|
-
}
|
|
1051
|
+
...props,
|
|
1052
|
+
className: cn("mt-3 mb-1 text-lg font-semibold", props.className),
|
|
1053
|
+
children
|
|
1054
|
+
}
|
|
1055
|
+
),
|
|
1056
|
+
h3: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
1057
|
+
"h3",
|
|
1058
|
+
{
|
|
1059
|
+
...props,
|
|
1060
|
+
className: cn("mt-2 mb-1 text-base font-semibold", props.className),
|
|
1061
|
+
children
|
|
1062
|
+
}
|
|
1063
|
+
),
|
|
1064
|
+
h4: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
1065
|
+
"h4",
|
|
1066
|
+
{
|
|
1067
|
+
...props,
|
|
1068
|
+
className: cn("mt-2 mb-1 text-sm font-semibold", props.className),
|
|
1069
|
+
children
|
|
813
1070
|
}
|
|
814
|
-
|
|
815
|
-
...
|
|
1071
|
+
),
|
|
1072
|
+
h5: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
1073
|
+
"h5",
|
|
816
1074
|
{
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
onSelect: startEdit
|
|
1075
|
+
...props,
|
|
1076
|
+
className: cn("mt-2 mb-1 text-sm font-semibold", props.className),
|
|
1077
|
+
children
|
|
821
1078
|
}
|
|
822
|
-
|
|
1079
|
+
),
|
|
1080
|
+
h6: ({ node: _node, children, ...props }) => /* @__PURE__ */ jsx(
|
|
1081
|
+
"h6",
|
|
1082
|
+
{
|
|
1083
|
+
...props,
|
|
1084
|
+
className: cn(
|
|
1085
|
+
"mt-2 mb-1 text-xs font-semibold tracking-wide uppercase",
|
|
1086
|
+
props.className
|
|
1087
|
+
),
|
|
1088
|
+
children
|
|
1089
|
+
}
|
|
1090
|
+
),
|
|
1091
|
+
hr: ({ node: _node, ...props }) => /* @__PURE__ */ jsx(
|
|
1092
|
+
"hr",
|
|
1093
|
+
{
|
|
1094
|
+
...props,
|
|
1095
|
+
className: cn(
|
|
1096
|
+
"my-2 border-neutral-300 dark:border-neutral-600",
|
|
1097
|
+
props.className
|
|
1098
|
+
)
|
|
1099
|
+
}
|
|
1100
|
+
)
|
|
1101
|
+
};
|
|
1102
|
+
}
|
|
1103
|
+
function createMarkdownRenderer(options = {}) {
|
|
1104
|
+
const { plugins = [], trusted = false } = options;
|
|
1105
|
+
const remarkPlugins = [
|
|
1106
|
+
remarkGfm,
|
|
1107
|
+
remarkPreserveLineBreaks,
|
|
1108
|
+
...plugins.flatMap((p) => p.remarkPlugins ?? [])
|
|
823
1109
|
];
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
{
|
|
827
|
-
"data-slot": "superchat-message",
|
|
828
|
-
role: "article",
|
|
829
|
-
"aria-label": `${authorName}, ${formatTime(message.time)}`,
|
|
830
|
-
className: cn(
|
|
831
|
-
"group flex gap-2",
|
|
832
|
-
isSelf ? "flex-row-reverse" : "flex-row"
|
|
833
|
-
),
|
|
834
|
-
children: [
|
|
835
|
-
/* @__PURE__ */ jsx(ParticipantAvatar, { participant }),
|
|
836
|
-
/* @__PURE__ */ jsxs("div", { className: cn("flex min-w-0 flex-col gap-1", isSelf && "items-end"), children: [
|
|
837
|
-
/* @__PURE__ */ jsxs(
|
|
838
|
-
"div",
|
|
839
|
-
{
|
|
840
|
-
"data-slot": "superchat-message-meta",
|
|
841
|
-
className: "flex items-baseline gap-2",
|
|
842
|
-
children: [
|
|
843
|
-
/* @__PURE__ */ jsx(
|
|
844
|
-
"span",
|
|
845
|
-
{
|
|
846
|
-
className: "text-xs font-medium",
|
|
847
|
-
style: accentTextColor ? { color: accentTextColor } : void 0,
|
|
848
|
-
children: authorName
|
|
849
|
-
}
|
|
850
|
-
),
|
|
851
|
-
participant?.role && /* @__PURE__ */ jsx("span", { className: "text-[10px] text-neutral-500 dark:text-neutral-400", children: participant.role }),
|
|
852
|
-
/* @__PURE__ */ jsx("span", { className: "text-[10px] text-neutral-500 dark:text-neutral-400", children: formatTime(message.time) }),
|
|
853
|
-
message.editedAt && /* @__PURE__ */ jsx(
|
|
854
|
-
"span",
|
|
855
|
-
{
|
|
856
|
-
"data-slot": "superchat-edited-indicator",
|
|
857
|
-
className: "text-[10px] text-neutral-500 dark:text-neutral-400",
|
|
858
|
-
title: `Edited ${formatTime(message.editedAt)}`,
|
|
859
|
-
children: "(edited)"
|
|
860
|
-
}
|
|
861
|
-
)
|
|
862
|
-
]
|
|
863
|
-
}
|
|
864
|
-
),
|
|
865
|
-
/* @__PURE__ */ jsxs(
|
|
866
|
-
"div",
|
|
867
|
-
{
|
|
868
|
-
className: cn(
|
|
869
|
-
"flex items-center gap-1",
|
|
870
|
-
isSelf ? "flex-row-reverse" : "flex-row"
|
|
871
|
-
),
|
|
872
|
-
children: [
|
|
873
|
-
hasActions && /* @__PURE__ */ jsx(
|
|
874
|
-
MessageOverflowMenu,
|
|
875
|
-
{
|
|
876
|
-
isSelf,
|
|
877
|
-
actions,
|
|
878
|
-
footerVisible
|
|
879
|
-
}
|
|
880
|
-
),
|
|
881
|
-
/* @__PURE__ */ jsx(
|
|
882
|
-
ChatBubble,
|
|
883
|
-
{
|
|
884
|
-
ref: bubbleRef,
|
|
885
|
-
"data-slot": "superchat-bubble",
|
|
886
|
-
variant: isSelf ? "user" : "assistant",
|
|
887
|
-
hasError: message.status === "error",
|
|
888
|
-
className: "text-sm has-[[data-slot=superchat-nitro-table]]:w-full has-[[data-slot=superchat-nitro-table]]:max-w-full",
|
|
889
|
-
children: isEditing ? /* @__PURE__ */ jsxs(
|
|
890
|
-
"div",
|
|
891
|
-
{
|
|
892
|
-
"data-slot": "superchat-message-editor",
|
|
893
|
-
className: "flex w-80 max-w-full flex-col gap-2",
|
|
894
|
-
children: [
|
|
895
|
-
/* @__PURE__ */ jsx(
|
|
896
|
-
"textarea",
|
|
897
|
-
{
|
|
898
|
-
value: draft,
|
|
899
|
-
ref: editRef,
|
|
900
|
-
rows: 2,
|
|
901
|
-
onChange: (e) => {
|
|
902
|
-
setDraft(e.target.value);
|
|
903
|
-
autosize();
|
|
904
|
-
},
|
|
905
|
-
onPaste: handleEditPaste,
|
|
906
|
-
onKeyDown: (e) => {
|
|
907
|
-
if (e.key === "Enter" && !e.shiftKey) {
|
|
908
|
-
e.preventDefault();
|
|
909
|
-
saveEdit();
|
|
910
|
-
} else if (e.key === "Escape") {
|
|
911
|
-
e.preventDefault();
|
|
912
|
-
cancelEdit();
|
|
913
|
-
}
|
|
914
|
-
},
|
|
915
|
-
"aria-label": "Edit message",
|
|
916
|
-
className: "focus:ring-primary-500 max-h-60 min-h-16 w-full resize-none rounded-lg border border-neutral-300 bg-white px-3 py-2 text-sm text-neutral-900 focus:ring-1 focus:outline-none dark:border-neutral-600 dark:bg-neutral-900 dark:text-white"
|
|
917
|
-
}
|
|
918
|
-
),
|
|
919
|
-
/* @__PURE__ */ jsxs("div", { className: "flex justify-end gap-2", children: [
|
|
920
|
-
/* @__PURE__ */ jsx(
|
|
921
|
-
"button",
|
|
922
|
-
{
|
|
923
|
-
type: "button",
|
|
924
|
-
onClick: cancelEdit,
|
|
925
|
-
className: "rounded-md px-2.5 py-1 text-xs font-medium text-neutral-200 hover:bg-white/10",
|
|
926
|
-
children: "Cancel"
|
|
927
|
-
}
|
|
928
|
-
),
|
|
929
|
-
/* @__PURE__ */ jsx(
|
|
930
|
-
"button",
|
|
931
|
-
{
|
|
932
|
-
type: "button",
|
|
933
|
-
onClick: saveEdit,
|
|
934
|
-
disabled: !draft.trim() || draft.trim() === message.text,
|
|
935
|
-
className: "rounded-md bg-white px-2.5 py-1 text-xs font-medium text-neutral-900 hover:bg-neutral-100 disabled:opacity-40",
|
|
936
|
-
children: "Save"
|
|
937
|
-
}
|
|
938
|
-
)
|
|
939
|
-
] })
|
|
940
|
-
]
|
|
941
|
-
}
|
|
942
|
-
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
943
|
-
message.content?.map((block, i) => {
|
|
944
|
-
if (block.type === "tool_use" && block.toolCall) {
|
|
945
|
-
return /* @__PURE__ */ jsx(MCPToolCallDisplay, { toolCall: block.toolCall }, i);
|
|
946
|
-
}
|
|
947
|
-
if ((block.type === "text" || block.type === "thinking") && block.text) {
|
|
948
|
-
return /* @__PURE__ */ jsx(
|
|
949
|
-
"div",
|
|
950
|
-
{
|
|
951
|
-
className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word",
|
|
952
|
-
children: renderText(block.text, {
|
|
953
|
-
messageId: message.id,
|
|
954
|
-
streaming,
|
|
955
|
-
role: participant?.kind === "human" ? "user" : "assistant"
|
|
956
|
-
})
|
|
957
|
-
},
|
|
958
|
-
i
|
|
959
|
-
);
|
|
960
|
-
}
|
|
961
|
-
if (block.type === "code" && block.text) {
|
|
962
|
-
const fenced = `\`\`\`${block.language ?? ""}
|
|
963
|
-
${block.text}
|
|
964
|
-
\`\`\``;
|
|
965
|
-
return /* @__PURE__ */ jsx(
|
|
966
|
-
"div",
|
|
967
|
-
{
|
|
968
|
-
className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word",
|
|
969
|
-
children: renderText(fenced, {
|
|
970
|
-
messageId: message.id,
|
|
971
|
-
streaming,
|
|
972
|
-
role: participant?.kind === "human" ? "user" : "assistant"
|
|
973
|
-
})
|
|
974
|
-
},
|
|
975
|
-
i
|
|
976
|
-
);
|
|
977
|
-
}
|
|
978
|
-
return null;
|
|
979
|
-
}),
|
|
980
|
-
message.text && /* @__PURE__ */ jsx("div", { className: "prose prose-sm dark:prose-invert max-w-none **:wrap-break-word", children: renderText(message.text, {
|
|
981
|
-
messageId: message.id,
|
|
982
|
-
streaming,
|
|
983
|
-
role: participant?.kind === "human" ? "user" : "assistant"
|
|
984
|
-
}) }),
|
|
985
|
-
streaming && !hasBody && /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(AITypingIndicator, {}) })
|
|
986
|
-
] })
|
|
987
|
-
}
|
|
988
|
-
)
|
|
989
|
-
]
|
|
990
|
-
}
|
|
991
|
-
),
|
|
992
|
-
hasActions && /* @__PURE__ */ jsx(
|
|
993
|
-
MessageActionsBar,
|
|
994
|
-
{
|
|
995
|
-
ref: actionsBarRef,
|
|
996
|
-
actions,
|
|
997
|
-
isSelf
|
|
998
|
-
}
|
|
999
|
-
)
|
|
1000
|
-
] })
|
|
1001
|
-
]
|
|
1002
|
-
}
|
|
1110
|
+
const pluginRehype = plugins.flatMap(
|
|
1111
|
+
(p) => p.rehypePlugins ?? []
|
|
1003
1112
|
);
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1113
|
+
const sanitizeSchema = plugins.reduce(
|
|
1114
|
+
(acc, p) => mergeSanitizeSchema(acc, p.sanitizeSchema),
|
|
1115
|
+
baseSanitizeSchema()
|
|
1116
|
+
);
|
|
1117
|
+
const rehypePlugins = trusted ? pluginRehype : [...pluginRehype, [rehypeSanitize, sanitizeSchema]];
|
|
1118
|
+
const components = plugins.reduce(
|
|
1119
|
+
(acc, p) => ({ ...acc, ...p.components }),
|
|
1120
|
+
baseComponents()
|
|
1121
|
+
);
|
|
1122
|
+
const MarkdownRenderer = (text, ctx) => /* @__PURE__ */ jsx(
|
|
1123
|
+
MarkdownContent,
|
|
1124
|
+
{
|
|
1125
|
+
text,
|
|
1126
|
+
messageId: ctx.messageId,
|
|
1127
|
+
streaming: ctx.streaming,
|
|
1128
|
+
remarkPlugins,
|
|
1129
|
+
rehypePlugins,
|
|
1130
|
+
components
|
|
1013
1131
|
},
|
|
1014
|
-
|
|
1132
|
+
ctx.messageId
|
|
1133
|
+
);
|
|
1134
|
+
return MarkdownRenderer;
|
|
1135
|
+
}
|
|
1136
|
+
var transformUrl = (url, key, node) => {
|
|
1137
|
+
if (key === "src" && node.tagName === "img" && (/^data:image\//i.test(url) || /^blob:/i.test(url))) {
|
|
1138
|
+
return url;
|
|
1015
1139
|
}
|
|
1016
|
-
);
|
|
1140
|
+
return defaultUrlTransform(url);
|
|
1141
|
+
};
|
|
1142
|
+
var MarkdownContent = React3.memo(function MarkdownContent2({
|
|
1143
|
+
text,
|
|
1144
|
+
messageId,
|
|
1145
|
+
streaming,
|
|
1146
|
+
remarkPlugins,
|
|
1147
|
+
rehypePlugins,
|
|
1148
|
+
components
|
|
1149
|
+
}) {
|
|
1150
|
+
return /* @__PURE__ */ jsx(TextRenderContext.Provider, { value: { messageId, streaming }, children: /* @__PURE__ */ jsx(
|
|
1151
|
+
Markdown,
|
|
1152
|
+
{
|
|
1153
|
+
remarkPlugins,
|
|
1154
|
+
rehypePlugins,
|
|
1155
|
+
urlTransform: transformUrl,
|
|
1156
|
+
components,
|
|
1157
|
+
children: text
|
|
1158
|
+
}
|
|
1159
|
+
) });
|
|
1160
|
+
});
|
|
1017
1161
|
function VirtualThread({
|
|
1018
1162
|
items,
|
|
1019
1163
|
participantById,
|
|
@@ -1024,32 +1168,28 @@ function VirtualThread({
|
|
|
1024
1168
|
editable,
|
|
1025
1169
|
onMessageEdited,
|
|
1026
1170
|
defaultCopyFormat,
|
|
1027
|
-
|
|
1028
|
-
|
|
1171
|
+
onOpenMedia,
|
|
1172
|
+
openMediaLabel,
|
|
1173
|
+
playMediaLabel,
|
|
1174
|
+
mediaErrorLabel,
|
|
1175
|
+
mediaRetryLabel,
|
|
1176
|
+
scrollRef,
|
|
1177
|
+
contentRef,
|
|
1029
1178
|
containerProps
|
|
1030
1179
|
}) {
|
|
1031
|
-
const parentRef = React2.useRef(null);
|
|
1032
1180
|
const virtualizer = useVirtualizer({
|
|
1033
1181
|
count: items.length,
|
|
1034
|
-
getScrollElement: () =>
|
|
1182
|
+
getScrollElement: () => scrollRef.current,
|
|
1035
1183
|
// Rough first guess; real heights are measured via measureElement.
|
|
1036
1184
|
estimateSize: () => 88,
|
|
1037
1185
|
overscan: 10,
|
|
1038
1186
|
getItemKey: (index) => items[index]?.id ?? index
|
|
1039
1187
|
});
|
|
1040
|
-
const count = items.length;
|
|
1041
|
-
React2.useEffect(() => {
|
|
1042
|
-
if (count === 0) return;
|
|
1043
|
-
if (order === "desc") {
|
|
1044
|
-
virtualizer.scrollToIndex(0, { align: "start" });
|
|
1045
|
-
} else {
|
|
1046
|
-
virtualizer.scrollToIndex(count - 1, { align: "end" });
|
|
1047
|
-
}
|
|
1048
|
-
}, [count, conversationId, order]);
|
|
1049
1188
|
const virtualItems = virtualizer.getVirtualItems();
|
|
1050
|
-
return /* @__PURE__ */ jsx("div", { ...containerProps, ref:
|
|
1189
|
+
return /* @__PURE__ */ jsx("div", { ...containerProps, ref: scrollRef, children: /* @__PURE__ */ jsx(
|
|
1051
1190
|
"div",
|
|
1052
1191
|
{
|
|
1192
|
+
ref: contentRef,
|
|
1053
1193
|
style: {
|
|
1054
1194
|
height: virtualizer.getTotalSize(),
|
|
1055
1195
|
position: "relative",
|
|
@@ -1081,7 +1221,12 @@ function VirtualThread({
|
|
|
1081
1221
|
onReferenceClick,
|
|
1082
1222
|
editable,
|
|
1083
1223
|
onMessageEdited,
|
|
1084
|
-
defaultCopyFormat
|
|
1224
|
+
defaultCopyFormat,
|
|
1225
|
+
onOpenMedia,
|
|
1226
|
+
openMediaLabel,
|
|
1227
|
+
playMediaLabel,
|
|
1228
|
+
mediaErrorLabel,
|
|
1229
|
+
mediaRetryLabel
|
|
1085
1230
|
}
|
|
1086
1231
|
) })
|
|
1087
1232
|
},
|
|
@@ -1093,6 +1238,11 @@ function VirtualThread({
|
|
|
1093
1238
|
}
|
|
1094
1239
|
function SuperChat({
|
|
1095
1240
|
conversation,
|
|
1241
|
+
view,
|
|
1242
|
+
defaultView = "thread",
|
|
1243
|
+
onViewChange,
|
|
1244
|
+
mediaFeedProps,
|
|
1245
|
+
mediaLabels,
|
|
1096
1246
|
currentParticipantId,
|
|
1097
1247
|
renderPlugins,
|
|
1098
1248
|
renderTextContent,
|
|
@@ -1110,38 +1260,349 @@ function SuperChat({
|
|
|
1110
1260
|
onReferenceClick,
|
|
1111
1261
|
onBack
|
|
1112
1262
|
}) {
|
|
1113
|
-
const headingId =
|
|
1114
|
-
|
|
1263
|
+
const headingId = React3.useId();
|
|
1264
|
+
const [internalView, setInternalView] = React3.useState({
|
|
1265
|
+
conversationId: conversation.id,
|
|
1266
|
+
view: defaultView
|
|
1267
|
+
});
|
|
1268
|
+
const activeView = view ?? (internalView.conversationId === conversation.id ? internalView.view : "thread");
|
|
1269
|
+
const labels = {
|
|
1270
|
+
backToConversation: "Back to conversation",
|
|
1271
|
+
openMedia: "Open in media feed",
|
|
1272
|
+
playMedia: "Play",
|
|
1273
|
+
unknownAuthor: "Unknown",
|
|
1274
|
+
...mediaLabels
|
|
1275
|
+
};
|
|
1276
|
+
const mediaItems = React3.useMemo(() => {
|
|
1277
|
+
const items = getConversationMediaItems(conversation);
|
|
1278
|
+
return order === "desc" ? items.reverse() : items;
|
|
1279
|
+
}, [conversation, order]);
|
|
1280
|
+
const [mediaSelection, setMediaSelection] = React3.useState();
|
|
1281
|
+
const [manualPlaybackRequest, setManualPlaybackRequest] = React3.useState();
|
|
1282
|
+
const playbackRequestCounter = React3.useRef(0);
|
|
1283
|
+
const mediaFeedRef = React3.useRef(null);
|
|
1284
|
+
const backToConversationRef = React3.useRef(null);
|
|
1285
|
+
const focusMediaOnOpenRef = React3.useRef(false);
|
|
1286
|
+
const focusThreadOnBackRef = React3.useRef(false);
|
|
1287
|
+
const mediaReturnTargetRef = React3.useRef(void 0);
|
|
1288
|
+
const mediaContextRef = React3.useRef({
|
|
1289
|
+
conversation,
|
|
1290
|
+
view,
|
|
1291
|
+
onViewChange,
|
|
1292
|
+
mediaFeedProps,
|
|
1293
|
+
mediaItems
|
|
1294
|
+
});
|
|
1295
|
+
mediaContextRef.current = {
|
|
1296
|
+
conversation,
|
|
1297
|
+
view,
|
|
1298
|
+
onViewChange,
|
|
1299
|
+
mediaFeedProps,
|
|
1300
|
+
mediaItems
|
|
1301
|
+
};
|
|
1302
|
+
const setView = React3.useCallback((next) => {
|
|
1303
|
+
const context = mediaContextRef.current;
|
|
1304
|
+
if (context.view === void 0)
|
|
1305
|
+
setInternalView({ conversationId: context.conversation.id, view: next });
|
|
1306
|
+
context.onViewChange?.(next, { conversation: context.conversation });
|
|
1307
|
+
}, []);
|
|
1308
|
+
const handleMediaSelection = React3.useCallback((item) => {
|
|
1309
|
+
setMediaSelection({ conversationId: item.conversationId, itemId: item.id });
|
|
1310
|
+
mediaContextRef.current.mediaFeedProps?.onActiveItemChange?.(item);
|
|
1311
|
+
}, []);
|
|
1312
|
+
const handleOpenMedia = React3.useCallback(
|
|
1313
|
+
(messageId, attachmentId, play = false) => {
|
|
1314
|
+
const item = mediaContextRef.current.mediaItems.find(
|
|
1315
|
+
(candidate) => candidate.message.id === messageId && candidate.attachment.id === attachmentId
|
|
1316
|
+
);
|
|
1317
|
+
if (!item) return;
|
|
1318
|
+
handleMediaSelection(item);
|
|
1319
|
+
mediaReturnTargetRef.current = {
|
|
1320
|
+
conversationId: item.conversationId,
|
|
1321
|
+
messageId,
|
|
1322
|
+
attachmentId
|
|
1323
|
+
};
|
|
1324
|
+
focusMediaOnOpenRef.current = true;
|
|
1325
|
+
setManualPlaybackRequest(
|
|
1326
|
+
play ? {
|
|
1327
|
+
conversationId: item.conversationId,
|
|
1328
|
+
itemId: item.id,
|
|
1329
|
+
requestId: ++playbackRequestCounter.current
|
|
1330
|
+
} : void 0
|
|
1331
|
+
);
|
|
1332
|
+
setView("media");
|
|
1333
|
+
},
|
|
1334
|
+
[handleMediaSelection, setView]
|
|
1335
|
+
);
|
|
1336
|
+
const handleBackToConversation = React3.useCallback(() => {
|
|
1337
|
+
focusMediaOnOpenRef.current = false;
|
|
1338
|
+
focusThreadOnBackRef.current = true;
|
|
1339
|
+
setManualPlaybackRequest(void 0);
|
|
1340
|
+
setView("thread");
|
|
1341
|
+
}, [setView]);
|
|
1342
|
+
const hostPlaybackRequest = mediaFeedProps?.playbackRequest;
|
|
1343
|
+
const hostPlaybackKey = hostPlaybackRequest ? `${hostPlaybackRequest.itemId}\0${hostPlaybackRequest.requestId}` : void 0;
|
|
1344
|
+
React3.useEffect(() => {
|
|
1345
|
+
if (hostPlaybackKey === void 0) return;
|
|
1346
|
+
setManualPlaybackRequest(void 0);
|
|
1347
|
+
}, [hostPlaybackKey]);
|
|
1348
|
+
React3.useEffect(() => {
|
|
1349
|
+
if (internalView.conversationId !== conversation.id) {
|
|
1350
|
+
setInternalView({ conversationId: conversation.id, view: "thread" });
|
|
1351
|
+
}
|
|
1352
|
+
if (mediaReturnTargetRef.current?.conversationId !== conversation.id) {
|
|
1353
|
+
mediaReturnTargetRef.current = void 0;
|
|
1354
|
+
focusMediaOnOpenRef.current = false;
|
|
1355
|
+
focusThreadOnBackRef.current = false;
|
|
1356
|
+
setManualPlaybackRequest(void 0);
|
|
1357
|
+
}
|
|
1358
|
+
}, [conversation.id, internalView.conversationId]);
|
|
1359
|
+
React3.useEffect(() => {
|
|
1360
|
+
if (activeView !== "media" || !focusMediaOnOpenRef.current) return;
|
|
1361
|
+
const target = mediaFeedRef.current?.querySelector(
|
|
1362
|
+
'article[tabindex="0"]'
|
|
1363
|
+
) ?? mediaFeedRef.current?.querySelector('[role="feed"]');
|
|
1364
|
+
if (target) focusMediaOnOpenRef.current = false;
|
|
1365
|
+
(target ?? backToConversationRef.current)?.focus({ preventScroll: true });
|
|
1366
|
+
}, [
|
|
1367
|
+
activeView,
|
|
1368
|
+
mediaFeedProps?.loading,
|
|
1369
|
+
mediaFeedProps?.error,
|
|
1370
|
+
mediaItems.length
|
|
1371
|
+
]);
|
|
1372
|
+
React3.useEffect(() => {
|
|
1115
1373
|
notifyComposerMigrationOnce("SuperChat");
|
|
1116
1374
|
}, []);
|
|
1117
|
-
const renderText =
|
|
1375
|
+
const renderText = React3.useMemo(
|
|
1118
1376
|
() => renderTextContent ?? createMarkdownRenderer({
|
|
1119
1377
|
plugins: renderPlugins,
|
|
1120
1378
|
trusted: trustedContent
|
|
1121
1379
|
}),
|
|
1122
1380
|
[renderTextContent, renderPlugins, trustedContent]
|
|
1123
1381
|
);
|
|
1124
|
-
const
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1382
|
+
const prefersReducedMotion = usePrefersReducedMotion();
|
|
1383
|
+
const {
|
|
1384
|
+
containerRef: threadRef,
|
|
1385
|
+
contentRef: threadContentRef,
|
|
1386
|
+
isAtBottom,
|
|
1387
|
+
scrollToBottom,
|
|
1388
|
+
anchorToTurnStart,
|
|
1389
|
+
followIfPinned,
|
|
1390
|
+
stopFollowing
|
|
1391
|
+
} = useStickToBottom({
|
|
1392
|
+
disabled: order === "desc" || activeView === "media"
|
|
1393
|
+
});
|
|
1394
|
+
React3.useEffect(() => {
|
|
1395
|
+
if (activeView !== "thread") return;
|
|
1396
|
+
setManualPlaybackRequest(void 0);
|
|
1397
|
+
if (!focusThreadOnBackRef.current) return;
|
|
1398
|
+
focusThreadOnBackRef.current = false;
|
|
1399
|
+
const source = mediaReturnTargetRef.current;
|
|
1400
|
+
const launchId = source ? JSON.stringify([source.messageId, source.attachmentId]) : void 0;
|
|
1401
|
+
const launcher = source?.conversationId === conversation.id ? Array.from(
|
|
1402
|
+
threadRef.current?.querySelectorAll(
|
|
1403
|
+
"[data-media-launch-id]"
|
|
1404
|
+
) ?? []
|
|
1405
|
+
).find((button) => button.dataset.mediaLaunchId === launchId) : void 0;
|
|
1406
|
+
(launcher ?? threadRef.current)?.focus({ preventScroll: true });
|
|
1407
|
+
}, [activeView, conversation.id, threadRef]);
|
|
1408
|
+
const [hasNewBelow, setHasNewBelow] = React3.useState(false);
|
|
1409
|
+
const [turnStartId, setTurnStartId] = React3.useState(null);
|
|
1410
|
+
const [turnMinHeight, setTurnMinHeight] = React3.useState();
|
|
1411
|
+
const anchoredTurnRef = React3.useRef(null);
|
|
1412
|
+
const threadSnapshotRef = React3.useRef(void 0);
|
|
1413
|
+
const atBottomRef = React3.useRef(isAtBottom);
|
|
1414
|
+
atBottomRef.current = isAtBottom;
|
|
1415
|
+
const pendingMediaOwnSendRef = React3.useRef(false);
|
|
1416
|
+
const pendingMediaAppendRef = React3.useRef(false);
|
|
1417
|
+
React3.useEffect(() => {
|
|
1418
|
+
threadSnapshotRef.current = void 0;
|
|
1419
|
+
pendingMediaOwnSendRef.current = false;
|
|
1420
|
+
pendingMediaAppendRef.current = false;
|
|
1421
|
+
setTurnStartId(null);
|
|
1422
|
+
anchoredTurnRef.current = null;
|
|
1423
|
+
if (order === "desc") {
|
|
1424
|
+
const el = threadRef.current;
|
|
1425
|
+
if (el) el.scrollTop = 0;
|
|
1426
|
+
} else {
|
|
1427
|
+
scrollToBottom("auto");
|
|
1428
|
+
}
|
|
1429
|
+
setHasNewBelow(false);
|
|
1430
|
+
}, [conversation.id, order]);
|
|
1431
|
+
const threadLength = conversation.thread.length;
|
|
1432
|
+
const prevThreadLengthRef = React3.useRef(threadLength);
|
|
1433
|
+
const prevMessageIdsRef = React3.useRef(
|
|
1434
|
+
new Set(conversation.thread.map((message) => message.id))
|
|
1435
|
+
);
|
|
1436
|
+
const policyConversationRef = React3.useRef(conversation.id);
|
|
1437
|
+
const policyBaselinedRef = React3.useRef(false);
|
|
1438
|
+
React3.useEffect(() => {
|
|
1439
|
+
if (!policyBaselinedRef.current || policyConversationRef.current !== conversation.id) {
|
|
1440
|
+
policyBaselinedRef.current = true;
|
|
1441
|
+
policyConversationRef.current = conversation.id;
|
|
1442
|
+
prevThreadLengthRef.current = threadLength;
|
|
1443
|
+
prevMessageIdsRef.current = new Set(
|
|
1444
|
+
conversation.thread.map((message) => message.id)
|
|
1445
|
+
);
|
|
1446
|
+
if (order !== "desc" && [...conversation.thread].sort(byTime).at(-1)?.status === "streaming") {
|
|
1447
|
+
stopFollowing();
|
|
1448
|
+
}
|
|
1449
|
+
return;
|
|
1450
|
+
}
|
|
1451
|
+
if (threadLength === prevThreadLengthRef.current) return;
|
|
1452
|
+
const grew = threadLength > prevThreadLengthRef.current;
|
|
1453
|
+
prevThreadLengthRef.current = threadLength;
|
|
1454
|
+
if (grew && activeView === "media") pendingMediaAppendRef.current = true;
|
|
1455
|
+
if (order === "desc") {
|
|
1456
|
+
const el = threadRef.current;
|
|
1457
|
+
if (el) el.scrollTop = 0;
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1460
|
+
const prevIds = prevMessageIdsRef.current;
|
|
1461
|
+
let turnStart;
|
|
1462
|
+
if (grew && currentParticipantId) {
|
|
1463
|
+
for (const message of [...conversation.thread].sort(byTime)) {
|
|
1464
|
+
if (!prevIds.has(message.id) && message.participantId === currentParticipantId) {
|
|
1465
|
+
turnStart = message.id;
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
if (turnStart) {
|
|
1470
|
+
if (activeView === "media") pendingMediaOwnSendRef.current = true;
|
|
1471
|
+
if (virtualized) {
|
|
1472
|
+
scrollToBottom("auto");
|
|
1473
|
+
} else {
|
|
1474
|
+
setTurnStartId(turnStart);
|
|
1475
|
+
}
|
|
1476
|
+
} else if (grew) {
|
|
1477
|
+
const newest = [...conversation.thread].sort(byTime).at(-1);
|
|
1478
|
+
if (newest?.status === "streaming") {
|
|
1479
|
+
followIfPinned("auto");
|
|
1480
|
+
stopFollowing();
|
|
1481
|
+
} else if (!followIfPinned("auto")) {
|
|
1482
|
+
setHasNewBelow(true);
|
|
1483
|
+
}
|
|
1484
|
+
} else {
|
|
1485
|
+
followIfPinned("auto");
|
|
1486
|
+
}
|
|
1487
|
+
}, [threadLength, order, isAtBottom, conversation.id, activeView]);
|
|
1488
|
+
React3.useLayoutEffect(() => {
|
|
1489
|
+
if (activeView !== "thread") return;
|
|
1490
|
+
const container = threadRef.current;
|
|
1491
|
+
if (!container) return;
|
|
1492
|
+
const snapshot = threadSnapshotRef.current;
|
|
1493
|
+
const sameThread = snapshot?.conversationId === conversation.id && snapshot.order === order;
|
|
1494
|
+
const ownSend = pendingMediaOwnSendRef.current;
|
|
1495
|
+
const appended = pendingMediaAppendRef.current;
|
|
1496
|
+
pendingMediaOwnSendRef.current = false;
|
|
1497
|
+
pendingMediaAppendRef.current = false;
|
|
1498
|
+
if (order === "desc") {
|
|
1499
|
+
container.scrollTop = sameThread && !appended ? snapshot.scrollTop : 0;
|
|
1500
|
+
} else if (ownSend && !virtualized) ; else if (sameThread && !ownSend && (!snapshot.atBottom || !appended)) {
|
|
1501
|
+
container.scrollTop = snapshot.scrollTop;
|
|
1502
|
+
if (!snapshot.atBottom) stopFollowing();
|
|
1503
|
+
} else {
|
|
1504
|
+
scrollToBottom("auto");
|
|
1505
|
+
if ([...conversation.thread].sort(byTime).at(-1)?.status === "streaming")
|
|
1506
|
+
stopFollowing();
|
|
1507
|
+
}
|
|
1508
|
+
return () => {
|
|
1509
|
+
threadSnapshotRef.current = {
|
|
1510
|
+
conversationId: conversation.id,
|
|
1511
|
+
order,
|
|
1512
|
+
scrollTop: container.scrollTop,
|
|
1513
|
+
atBottom: atBottomRef.current
|
|
1514
|
+
};
|
|
1515
|
+
};
|
|
1516
|
+
}, [conversation.id, order, activeView, virtualized]);
|
|
1517
|
+
React3.useLayoutEffect(() => {
|
|
1518
|
+
if (!turnStartId || anchoredTurnRef.current === turnStartId) return;
|
|
1519
|
+
const container = threadRef.current;
|
|
1520
|
+
if (!container) return;
|
|
1521
|
+
const reserve = Math.max(0, container.clientHeight - 32);
|
|
1522
|
+
if (turnMinHeight !== reserve) {
|
|
1523
|
+
setTurnMinHeight(reserve);
|
|
1524
|
+
return;
|
|
1525
|
+
}
|
|
1526
|
+
const target = container.querySelector(
|
|
1527
|
+
'[data-slot="superchat-turn"]'
|
|
1528
|
+
);
|
|
1529
|
+
if (target) {
|
|
1530
|
+
anchorToTurnStart(target, prefersReducedMotion ? "auto" : "smooth");
|
|
1531
|
+
anchoredTurnRef.current = turnStartId;
|
|
1532
|
+
}
|
|
1533
|
+
}, [
|
|
1534
|
+
turnStartId,
|
|
1535
|
+
turnMinHeight,
|
|
1536
|
+
anchorToTurnStart,
|
|
1537
|
+
prefersReducedMotion,
|
|
1538
|
+
threadRef,
|
|
1539
|
+
activeView
|
|
1540
|
+
]);
|
|
1541
|
+
React3.useEffect(() => {
|
|
1542
|
+
prevMessageIdsRef.current = new Set(
|
|
1543
|
+
conversation.thread.map((message) => message.id)
|
|
1544
|
+
);
|
|
1545
|
+
});
|
|
1546
|
+
React3.useEffect(() => {
|
|
1547
|
+
if (isAtBottom) setHasNewBelow(false);
|
|
1548
|
+
}, [isAtBottom]);
|
|
1549
|
+
const newestMessage = React3.useMemo(
|
|
1550
|
+
() => [...conversation.thread].sort(byTime).at(-1),
|
|
1551
|
+
[conversation]
|
|
1552
|
+
);
|
|
1553
|
+
const raiseNewBelow = React3.useCallback(() => {
|
|
1554
|
+
if (order !== "desc") setHasNewBelow(true);
|
|
1555
|
+
}, [order]);
|
|
1556
|
+
const resumeFollowing = React3.useCallback(() => {
|
|
1557
|
+
if (order !== "desc") scrollToBottom("auto");
|
|
1558
|
+
}, [order, scrollToBottom]);
|
|
1559
|
+
useStreamEndedBelowFold(
|
|
1560
|
+
newestMessage,
|
|
1561
|
+
isAtBottom,
|
|
1562
|
+
raiseNewBelow,
|
|
1563
|
+
resumeFollowing
|
|
1564
|
+
);
|
|
1565
|
+
const handleJumpToBottom = React3.useCallback(() => {
|
|
1566
|
+
scrollToBottom(prefersReducedMotion ? "auto" : "smooth");
|
|
1567
|
+
}, [scrollToBottom, prefersReducedMotion]);
|
|
1568
|
+
const participantById = React3.useMemo(() => {
|
|
1132
1569
|
const map = /* @__PURE__ */ new Map();
|
|
1133
1570
|
conversation.participants.forEach((p) => map.set(p.id, p));
|
|
1134
1571
|
return map;
|
|
1135
1572
|
}, [conversation]);
|
|
1136
|
-
const orderedThread =
|
|
1573
|
+
const orderedThread = React3.useMemo(() => {
|
|
1137
1574
|
const sorted = [...conversation.thread].sort(byTime);
|
|
1138
1575
|
return order === "desc" ? sorted.reverse() : sorted;
|
|
1139
1576
|
}, [conversation, order]);
|
|
1140
|
-
const
|
|
1577
|
+
const turnIndex = React3.useMemo(
|
|
1578
|
+
() => turnStartId && order !== "desc" ? orderedThread.findIndex((message) => message.id === turnStartId) : -1,
|
|
1579
|
+
[orderedThread, turnStartId, order]
|
|
1580
|
+
);
|
|
1581
|
+
const renderMessageRow = (m) => /* @__PURE__ */ jsx(
|
|
1582
|
+
MessageRow,
|
|
1583
|
+
{
|
|
1584
|
+
message: m,
|
|
1585
|
+
participant: participantById.get(m.participantId),
|
|
1586
|
+
isSelf: !!currentParticipantId && m.participantId === currentParticipantId,
|
|
1587
|
+
renderText,
|
|
1588
|
+
linkBuilder,
|
|
1589
|
+
onReferenceClick,
|
|
1590
|
+
editable,
|
|
1591
|
+
onMessageEdited: handleMessageEdited,
|
|
1592
|
+
defaultCopyFormat,
|
|
1593
|
+
onOpenMedia: handleOpenMedia,
|
|
1594
|
+
openMediaLabel: labels.openMedia,
|
|
1595
|
+
playMediaLabel: labels.playMedia,
|
|
1596
|
+
mediaErrorLabel: mediaFeedProps?.labels?.mediaError,
|
|
1597
|
+
mediaRetryLabel: mediaFeedProps?.labels?.retry
|
|
1598
|
+
},
|
|
1599
|
+
m.id
|
|
1600
|
+
);
|
|
1601
|
+
const onMessageEditedRef = React3.useRef(onMessageEdited);
|
|
1141
1602
|
onMessageEditedRef.current = onMessageEdited;
|
|
1142
|
-
const conversationRef =
|
|
1603
|
+
const conversationRef = React3.useRef(conversation);
|
|
1143
1604
|
conversationRef.current = conversation;
|
|
1144
|
-
const handleMessageEdited =
|
|
1605
|
+
const handleMessageEdited = React3.useCallback(
|
|
1145
1606
|
(messageId, text) => {
|
|
1146
1607
|
onMessageEditedRef.current?.(messageId, text, {
|
|
1147
1608
|
conversation: conversationRef.current
|
|
@@ -1150,7 +1611,7 @@ function SuperChat({
|
|
|
1150
1611
|
[]
|
|
1151
1612
|
);
|
|
1152
1613
|
const editable = !readOnly && !!onMessageEdited;
|
|
1153
|
-
const mentionOptions =
|
|
1614
|
+
const mentionOptions = React3.useMemo(
|
|
1154
1615
|
() => conversation.participants.filter((p) => p.kind !== "system").map((p) => ({
|
|
1155
1616
|
id: p.id,
|
|
1156
1617
|
label: p.name,
|
|
@@ -1160,17 +1621,17 @@ function SuperChat({
|
|
|
1160
1621
|
})),
|
|
1161
1622
|
[conversation.participants]
|
|
1162
1623
|
);
|
|
1163
|
-
const composerAccept =
|
|
1624
|
+
const composerAccept = React3.useMemo(
|
|
1164
1625
|
() => acceptTokensFor(acceptedFileTypes),
|
|
1165
1626
|
[acceptedFileTypes]
|
|
1166
1627
|
);
|
|
1167
|
-
const [draft, setDraft] =
|
|
1168
|
-
const draftEpochRef =
|
|
1169
|
-
const handleDraftChange =
|
|
1628
|
+
const [draft, setDraft] = React3.useState("");
|
|
1629
|
+
const draftEpochRef = React3.useRef(0);
|
|
1630
|
+
const handleDraftChange = React3.useCallback((value) => {
|
|
1170
1631
|
draftEpochRef.current += 1;
|
|
1171
1632
|
setDraft(value);
|
|
1172
1633
|
}, []);
|
|
1173
|
-
const handleComposerSend =
|
|
1634
|
+
const handleComposerSend = React3.useCallback(
|
|
1174
1635
|
async (message) => {
|
|
1175
1636
|
const epoch = draftEpochRef.current;
|
|
1176
1637
|
try {
|
|
@@ -1266,55 +1727,129 @@ function SuperChat({
|
|
|
1266
1727
|
]
|
|
1267
1728
|
}
|
|
1268
1729
|
),
|
|
1269
|
-
|
|
1270
|
-
|
|
1730
|
+
activeView === "media" ? /* @__PURE__ */ jsxs(
|
|
1731
|
+
"div",
|
|
1271
1732
|
{
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1733
|
+
"data-slot": "superchat-media-view",
|
|
1734
|
+
className: "flex min-h-0 flex-1 flex-col",
|
|
1735
|
+
children: [
|
|
1736
|
+
/* @__PURE__ */ jsx("div", { className: "px-4 pt-2", children: /* @__PURE__ */ jsx(ButtonGroup, { className: "justify-start", children: /* @__PURE__ */ jsx(
|
|
1737
|
+
Button,
|
|
1738
|
+
{
|
|
1739
|
+
ref: backToConversationRef,
|
|
1740
|
+
variant: "ghost",
|
|
1741
|
+
size: "sm",
|
|
1742
|
+
leftIcon: /* @__PURE__ */ jsx(
|
|
1743
|
+
ArrowLeft,
|
|
1744
|
+
{
|
|
1745
|
+
className: "size-4 rtl:rotate-180",
|
|
1746
|
+
"aria-hidden": "true"
|
|
1747
|
+
}
|
|
1748
|
+
),
|
|
1749
|
+
onClick: handleBackToConversation,
|
|
1750
|
+
children: labels.backToConversation
|
|
1751
|
+
}
|
|
1752
|
+
) }) }),
|
|
1753
|
+
/* @__PURE__ */ createElement(
|
|
1754
|
+
MediaFeed,
|
|
1755
|
+
{
|
|
1756
|
+
...mediaFeedProps,
|
|
1757
|
+
ref: mediaFeedRef,
|
|
1758
|
+
key: conversation.id,
|
|
1759
|
+
items: mediaItems,
|
|
1760
|
+
getId: (item) => item.id,
|
|
1761
|
+
getMedia: (item) => item.attachment,
|
|
1762
|
+
getTitle: (item) => item.attachment.title ?? "",
|
|
1763
|
+
getCaption: (item) => item.attachment.caption ?? item.message.text,
|
|
1764
|
+
getAuthor: (item) => ({
|
|
1765
|
+
name: item.participant?.name ?? labels.unknownAuthor,
|
|
1766
|
+
avatar: item.participant?.avatar
|
|
1767
|
+
}),
|
|
1768
|
+
activeItemId: mediaFeedProps?.activeItemId ?? (mediaSelection?.conversationId === conversation.id ? mediaSelection.itemId : void 0),
|
|
1769
|
+
onActiveItemChange: handleMediaSelection,
|
|
1770
|
+
playbackRequest: manualPlaybackRequest?.conversationId === conversation.id ? manualPlaybackRequest : mediaFeedProps?.playbackRequest,
|
|
1771
|
+
className: cn("min-h-0 flex-1", mediaFeedProps?.className)
|
|
1772
|
+
}
|
|
1773
|
+
)
|
|
1774
|
+
]
|
|
1292
1775
|
}
|
|
1293
|
-
) : /* @__PURE__ */
|
|
1776
|
+
) : /* @__PURE__ */ jsxs(
|
|
1294
1777
|
"div",
|
|
1295
1778
|
{
|
|
1296
|
-
"data-slot": "superchat-thread",
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1779
|
+
"data-slot": "superchat-thread-viewport",
|
|
1780
|
+
className: "relative flex min-h-0 flex-1 flex-col",
|
|
1781
|
+
children: [
|
|
1782
|
+
virtualized ? /* @__PURE__ */ jsx(
|
|
1783
|
+
VirtualThread,
|
|
1784
|
+
{
|
|
1785
|
+
items: orderedThread,
|
|
1786
|
+
participantById,
|
|
1787
|
+
currentParticipantId,
|
|
1788
|
+
renderText,
|
|
1789
|
+
linkBuilder,
|
|
1790
|
+
onReferenceClick,
|
|
1791
|
+
editable,
|
|
1792
|
+
onMessageEdited: handleMessageEdited,
|
|
1793
|
+
defaultCopyFormat,
|
|
1794
|
+
onOpenMedia: handleOpenMedia,
|
|
1795
|
+
openMediaLabel: labels.openMedia,
|
|
1796
|
+
playMediaLabel: labels.playMedia,
|
|
1797
|
+
mediaErrorLabel: mediaFeedProps?.labels?.mediaError,
|
|
1798
|
+
mediaRetryLabel: mediaFeedProps?.labels?.retry,
|
|
1799
|
+
scrollRef: threadRef,
|
|
1800
|
+
contentRef: threadContentRef,
|
|
1801
|
+
containerProps: {
|
|
1802
|
+
"data-slot": "superchat-thread",
|
|
1803
|
+
role: "log",
|
|
1804
|
+
"aria-label": "Messages",
|
|
1805
|
+
"aria-live": "polite",
|
|
1806
|
+
// Focusable so keyboard-only users can scroll the message history.
|
|
1807
|
+
tabIndex: 0,
|
|
1808
|
+
className: "flex-1 overflow-y-auto p-4"
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
) : /* @__PURE__ */ jsx(
|
|
1812
|
+
"div",
|
|
1813
|
+
{
|
|
1814
|
+
"data-slot": "superchat-thread",
|
|
1815
|
+
ref: threadRef,
|
|
1816
|
+
role: "log",
|
|
1817
|
+
"aria-label": "Messages",
|
|
1818
|
+
"aria-live": "polite",
|
|
1819
|
+
tabIndex: 0,
|
|
1820
|
+
className: "flex-1 overflow-y-auto p-4",
|
|
1821
|
+
children: /* @__PURE__ */ jsxs("div", { ref: threadContentRef, className: "space-y-4", children: [
|
|
1822
|
+
(turnIndex === -1 ? orderedThread : orderedThread.slice(0, turnIndex)).map(renderMessageRow),
|
|
1823
|
+
turnIndex !== -1 && /* @__PURE__ */ jsx(
|
|
1824
|
+
"div",
|
|
1825
|
+
{
|
|
1826
|
+
"data-slot": "superchat-turn",
|
|
1827
|
+
className: "space-y-4",
|
|
1828
|
+
style: { minHeight: turnMinHeight },
|
|
1829
|
+
children: orderedThread.slice(turnIndex).map(renderMessageRow)
|
|
1830
|
+
}
|
|
1831
|
+
)
|
|
1832
|
+
] })
|
|
1833
|
+
}
|
|
1834
|
+
),
|
|
1835
|
+
/* @__PURE__ */ jsx(AnimatedPresence, { children: order !== "desc" && !isAtBottom && /* @__PURE__ */ jsx(
|
|
1836
|
+
Animated,
|
|
1837
|
+
{
|
|
1838
|
+
preset: "fade",
|
|
1839
|
+
mode: "presence",
|
|
1840
|
+
className: "absolute inset-x-0 bottom-0 z-20",
|
|
1841
|
+
children: /* @__PURE__ */ jsx(
|
|
1842
|
+
JumpToBottomButton,
|
|
1843
|
+
{
|
|
1844
|
+
dataSlot: "superchat-jump-to-bottom",
|
|
1845
|
+
hasNewMessages: hasNewBelow,
|
|
1846
|
+
onClick: handleJumpToBottom
|
|
1847
|
+
}
|
|
1848
|
+
)
|
|
1849
|
+
},
|
|
1850
|
+
"jump-to-bottom"
|
|
1851
|
+
) })
|
|
1852
|
+
]
|
|
1318
1853
|
}
|
|
1319
1854
|
),
|
|
1320
1855
|
/* @__PURE__ */ jsx(
|
|
@@ -1324,6 +1859,7 @@ function SuperChat({
|
|
|
1324
1859
|
onValueChange: handleDraftChange,
|
|
1325
1860
|
onSend: handleComposerSend,
|
|
1326
1861
|
disabled: readOnly,
|
|
1862
|
+
className: "px-4 pb-4",
|
|
1327
1863
|
placeholder: readOnly ? "Read-only conversation" : "Type a message\u2026 use @ to address an agent",
|
|
1328
1864
|
mentionOptions,
|
|
1329
1865
|
allowAttachments: !readOnly,
|
|
@@ -1345,12 +1881,14 @@ function SuperChatConversations({
|
|
|
1345
1881
|
onConversationOpened,
|
|
1346
1882
|
onNewConversation
|
|
1347
1883
|
}) {
|
|
1348
|
-
const [internalActive, setInternalActive] =
|
|
1884
|
+
const [internalActive, setInternalActive] = React3.useState(
|
|
1349
1885
|
defaultActiveConversationId ?? conversations[0]?.id
|
|
1350
1886
|
);
|
|
1887
|
+
const [hasMounted, setHasMounted] = React3.useState(false);
|
|
1888
|
+
React3.useEffect(() => setHasMounted(true), []);
|
|
1351
1889
|
const requestedId = activeConversationId ?? internalActive;
|
|
1352
1890
|
const activeId = conversations.some((c) => c.id === requestedId) ? requestedId : conversations[0]?.id;
|
|
1353
|
-
const sortedConversations =
|
|
1891
|
+
const sortedConversations = React3.useMemo(
|
|
1354
1892
|
() => [...conversations].sort((a, b) => lastActivityOf(b) - lastActivityOf(a)),
|
|
1355
1893
|
[conversations]
|
|
1356
1894
|
);
|
|
@@ -1402,10 +1940,21 @@ function SuperChatConversations({
|
|
|
1402
1940
|
/* @__PURE__ */ jsx("span", { className: "block truncate font-medium", children: c.title }),
|
|
1403
1941
|
last?.text && /* @__PURE__ */ jsx("span", { className: "block truncate text-xs text-neutral-600 dark:text-neutral-400", children: last.text })
|
|
1404
1942
|
] }),
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1943
|
+
/* @__PURE__ */ jsx(AnimatedPresence, { initial: hasMounted, children: !!c.unread && /* @__PURE__ */ jsxs(
|
|
1944
|
+
Animated,
|
|
1945
|
+
{
|
|
1946
|
+
as: "span",
|
|
1947
|
+
preset: "pop",
|
|
1948
|
+
mode: "presence",
|
|
1949
|
+
"data-slot": "superchat-unread-badge",
|
|
1950
|
+
className: "bg-primary-600 ms-1 inline-flex h-5 min-w-5 items-center justify-center rounded-full px-1.5 text-[10px] font-semibold text-white",
|
|
1951
|
+
children: [
|
|
1952
|
+
c.unread,
|
|
1953
|
+
/* @__PURE__ */ jsx("span", { className: "sr-only", children: " unread messages" })
|
|
1954
|
+
]
|
|
1955
|
+
},
|
|
1956
|
+
"unread"
|
|
1957
|
+
) })
|
|
1409
1958
|
]
|
|
1410
1959
|
}
|
|
1411
1960
|
) }, c.id);
|
|
@@ -1418,6 +1967,11 @@ function SuperChatConversations({
|
|
|
1418
1967
|
}
|
|
1419
1968
|
function SuperChatInbox({
|
|
1420
1969
|
conversations,
|
|
1970
|
+
view,
|
|
1971
|
+
defaultView,
|
|
1972
|
+
onViewChange,
|
|
1973
|
+
mediaFeedProps,
|
|
1974
|
+
mediaLabels,
|
|
1421
1975
|
activeConversationId,
|
|
1422
1976
|
defaultActiveConversationId,
|
|
1423
1977
|
currentParticipantId,
|
|
@@ -1439,13 +1993,13 @@ function SuperChatInbox({
|
|
|
1439
1993
|
onNewConversation,
|
|
1440
1994
|
onReferenceClick
|
|
1441
1995
|
}) {
|
|
1442
|
-
const [internalActive, setInternalActive] =
|
|
1996
|
+
const [internalActive, setInternalActive] = React3.useState(
|
|
1443
1997
|
defaultActiveConversationId ?? conversations[0]?.id
|
|
1444
1998
|
);
|
|
1445
1999
|
const requestedId = activeConversationId ?? internalActive;
|
|
1446
2000
|
const active = conversations.find((c) => c.id === requestedId) ?? conversations[0];
|
|
1447
2001
|
const activeId = active?.id;
|
|
1448
|
-
const [mobileView, setMobileView] =
|
|
2002
|
+
const [mobileView, setMobileView] = React3.useState("list");
|
|
1449
2003
|
const handleOpen = (c) => {
|
|
1450
2004
|
if (activeConversationId === void 0) setInternalActive(c.id);
|
|
1451
2005
|
setMobileView("chat");
|
|
@@ -1479,6 +2033,11 @@ function SuperChatInbox({
|
|
|
1479
2033
|
SuperChat,
|
|
1480
2034
|
{
|
|
1481
2035
|
conversation: active,
|
|
2036
|
+
view,
|
|
2037
|
+
defaultView,
|
|
2038
|
+
onViewChange,
|
|
2039
|
+
mediaFeedProps,
|
|
2040
|
+
mediaLabels,
|
|
1482
2041
|
currentParticipantId,
|
|
1483
2042
|
renderPlugins,
|
|
1484
2043
|
renderTextContent,
|
|
@@ -1514,6 +2073,6 @@ function SuperChatInbox({
|
|
|
1514
2073
|
);
|
|
1515
2074
|
}
|
|
1516
2075
|
|
|
1517
|
-
export { SuperChat, SuperChatConversations, SuperChatInbox, createMarkdownRenderer };
|
|
2076
|
+
export { SuperChat, SuperChatConversations, SuperChatInbox, createMarkdownRenderer, getConversationMediaItems };
|
|
1518
2077
|
//# sourceMappingURL=index.js.map
|
|
1519
2078
|
//# sourceMappingURL=index.js.map
|