stream-chat-react 14.0.0-beta.1 → 14.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/dist/{WithAudioPlayback-BcKZ5Lbh.mjs → WithAudioPlayback-C1hfFIcu.mjs} +349 -256
  2. package/dist/WithAudioPlayback-C1hfFIcu.mjs.map +1 -0
  3. package/dist/{WithAudioPlayback-TERIQpZ6.js → WithAudioPlayback-myzUS2m6.js} +101 -8
  4. package/dist/WithAudioPlayback-myzUS2m6.js.map +1 -0
  5. package/dist/cjs/emojis.js +1 -1
  6. package/dist/cjs/index.js +703 -769
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/css/index.css +51 -36
  9. package/dist/css/index.css.map +1 -1
  10. package/dist/es/emojis.mjs +1 -1
  11. package/dist/es/index.mjs +827 -893
  12. package/dist/es/index.mjs.map +1 -1
  13. package/dist/types/components/Badge/Badge.d.ts +1 -0
  14. package/dist/types/components/Badge/Badge.d.ts.map +1 -1
  15. package/dist/types/components/Channel/Channel.d.ts.map +1 -1
  16. package/dist/types/components/Channel/utils.d.ts +7 -1
  17. package/dist/types/components/Channel/utils.d.ts.map +1 -1
  18. package/dist/types/components/ChatView/ChatView.d.ts.map +1 -1
  19. package/dist/types/components/Gallery/Gallery.d.ts.map +1 -1
  20. package/dist/types/components/Icons/icons.d.ts +4 -0
  21. package/dist/types/components/Icons/icons.d.ts.map +1 -1
  22. package/dist/types/components/MediaRecorder/AudioRecorder/AudioRecorderRecordingControls.d.ts.map +1 -1
  23. package/dist/types/components/Message/MessageErrorText.d.ts +0 -5
  24. package/dist/types/components/Message/MessageErrorText.d.ts.map +1 -1
  25. package/dist/types/components/Message/MessageText.d.ts.map +1 -1
  26. package/dist/types/components/Message/MessageUI.d.ts.map +1 -1
  27. package/dist/types/components/Message/hooks/useDeleteHandler.d.ts.map +1 -1
  28. package/dist/types/components/Message/index.d.ts +0 -1
  29. package/dist/types/components/Message/index.d.ts.map +1 -1
  30. package/dist/types/components/Message/utils.d.ts +1 -0
  31. package/dist/types/components/Message/utils.d.ts.map +1 -1
  32. package/dist/types/components/MessageActions/MessageActions.d.ts.map +1 -1
  33. package/dist/types/components/MessageActions/MessageActions.defaults.d.ts.map +1 -1
  34. package/dist/types/components/MessageActions/hooks/useBaseMessageActionSetFilter.d.ts.map +1 -1
  35. package/dist/types/components/MessageComposer/AttachmentPreviewList/AttachmentPreviewList.d.ts.map +1 -1
  36. package/dist/types/components/MessageComposer/AttachmentPreviewList/ImageAttachmentPreview.d.ts +3 -1
  37. package/dist/types/components/MessageComposer/AttachmentPreviewList/ImageAttachmentPreview.d.ts.map +1 -1
  38. package/dist/types/components/MessageComposer/AttachmentPreviewList/MediaAttachmentPreview.d.ts +4 -2
  39. package/dist/types/components/MessageComposer/AttachmentPreviewList/MediaAttachmentPreview.d.ts.map +1 -1
  40. package/dist/types/components/MessageComposer/AttachmentPreviewList/utils/AttachmentPreviewRoot.d.ts +6 -1
  41. package/dist/types/components/MessageComposer/AttachmentPreviewList/utils/AttachmentPreviewRoot.d.ts.map +1 -1
  42. package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts +9 -2
  43. package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts.map +1 -1
  44. package/dist/types/components/MessageComposer/CommandChip.d.ts +5 -1
  45. package/dist/types/components/MessageComposer/CommandChip.d.ts.map +1 -1
  46. package/dist/types/components/MessageComposer/MessageComposerUI.d.ts.map +1 -1
  47. package/dist/types/components/Notifications/Notification.d.ts.map +1 -1
  48. package/dist/types/components/Notifications/hooks/useNotificationTarget.d.ts +1 -1
  49. package/dist/types/components/Notifications/hooks/useNotificationTarget.d.ts.map +1 -1
  50. package/dist/types/components/Notifications/notificationTarget.d.ts +1 -1
  51. package/dist/types/components/Notifications/notificationTarget.d.ts.map +1 -1
  52. package/dist/types/components/Poll/PollOptionSelector.d.ts.map +1 -1
  53. package/dist/types/components/TextareaComposer/TextareaComposer.d.ts +1 -2
  54. package/dist/types/components/TextareaComposer/TextareaComposer.d.ts.map +1 -1
  55. package/dist/types/context/ComponentContext.d.ts +5 -2
  56. package/dist/types/context/ComponentContext.d.ts.map +1 -1
  57. package/dist/types/i18n/Streami18n.d.ts +11 -6
  58. package/dist/types/i18n/Streami18n.d.ts.map +1 -1
  59. package/package.json +11 -41
  60. package/dist/WithAudioPlayback-BcKZ5Lbh.mjs.map +0 -1
  61. package/dist/WithAudioPlayback-TERIQpZ6.js.map +0 -1
  62. package/dist/types/components/Message/icons.d.ts +0 -7
  63. package/dist/types/components/Message/icons.d.ts.map +0 -1
package/dist/cjs/index.js CHANGED
@@ -5,7 +5,7 @@ const clsx = require("clsx");
5
5
  const nanoid = require("nanoid");
6
6
  const React = require("react");
7
7
  const audioProcessing = require("../audioProcessing-BbOs2wMd.js");
8
- const WithAudioPlayback = require("../WithAudioPlayback-TERIQpZ6.js");
8
+ const WithAudioPlayback = require("../WithAudioPlayback-myzUS2m6.js");
9
9
  const streamChat = require("stream-chat");
10
10
  const throttle = require("lodash.throttle");
11
11
  const linkify = require("linkifyjs");
@@ -88,23 +88,6 @@ const useAIState = (channel) => {
88
88
  }, [channel]);
89
89
  return { aiState };
90
90
  };
91
- const ChannelListContext = React.createContext(
92
- void 0
93
- );
94
- const ChannelListContextProvider = ({
95
- children,
96
- value
97
- }) => /* @__PURE__ */ jsxRuntime.jsx(ChannelListContext.Provider, { value, children });
98
- const useChannelListContext = (componentName) => {
99
- const contextValue = React.useContext(ChannelListContext);
100
- if (!contextValue) {
101
- console.warn(
102
- `The useChannelListContext hook was called outside of the ChannelListContext provider. Make sure this hook is called within the ChannelList component. The errored call is located in the ${componentName} component.`
103
- );
104
- return {};
105
- }
106
- return contextValue;
107
- };
108
91
  class DialogManager {
109
92
  constructor({ id } = {}) {
110
93
  this.state = new streamChat.StateStore({
@@ -967,7 +950,6 @@ const deTranslations = {
967
950
  "End vote": "Abstimmung beenden",
968
951
  "Enforce unique vote is enabled": "Eindeutige Abstimmung ist aktiviert",
969
952
  "Error": "Fehler",
970
- "Error · Unsent": "Fehler · Nicht gesendet",
971
953
  "Error adding flag": "Fehler beim Hinzufügen des Flags",
972
954
  "Error connecting to chat, refresh the page to try again.": "Verbindungsfehler zum Chat, aktualisieren Sie die Seite, um es erneut zu versuchen.",
973
955
  "Error deleting message": "Fehler beim Löschen der Nachricht",
@@ -1089,8 +1071,6 @@ const deTranslations = {
1089
1071
  "Maximum number of votes (from 2 to 10)": "Maximale Anzahl der Stimmen (von 2 bis 10)",
1090
1072
  Menu: Menu$b,
1091
1073
  "Message deleted": "Nachricht gelöscht",
1092
- "Message Failed · Click to try again": "Nachricht fehlgeschlagen · Klicken, um es erneut zu versuchen",
1093
- "Message Failed · Unauthorized": "Nachricht fehlgeschlagen · Nicht autorisiert",
1094
1074
  "Message failed to send": "Nachricht konnte nicht gesendet werden",
1095
1075
  "Message has been successfully flagged": "Nachricht wurde erfolgreich gemeldet",
1096
1076
  "Message pinned": "Nachricht angeheftet",
@@ -1260,6 +1240,7 @@ const deTranslations = {
1260
1240
  "View translation": "Übersetzung anzeigen",
1261
1241
  "Voice message": "Sprachnachricht",
1262
1242
  "Voice message {{ duration }}": "Sprachnachricht {{ duration }}",
1243
+ "Voice message deleted": "Sprachnachricht gelöscht",
1263
1244
  voiceMessageCount_one: voiceMessageCount_one$9,
1264
1245
  voiceMessageCount_other: voiceMessageCount_other$b,
1265
1246
  "Vote ended": "Abstimmung beendet",
@@ -1490,7 +1471,6 @@ const enTranslations = {
1490
1471
  "End vote": "End Vote",
1491
1472
  "Enforce unique vote is enabled": "Enforce unique vote is enabled",
1492
1473
  "Error": "Error",
1493
- "Error · Unsent": "Error · Unsent",
1494
1474
  "Error adding flag": "Error adding flag",
1495
1475
  "Error connecting to chat, refresh the page to try again.": "Error connecting to chat, refresh the page to try again.",
1496
1476
  "Error deleting message": "Error deleting message",
@@ -1612,8 +1592,6 @@ const enTranslations = {
1612
1592
  "Maximum number of votes (from 2 to 10)": "Maximum number of votes (from 2 to 10)",
1613
1593
  Menu: Menu$a,
1614
1594
  "Message deleted": "Message deleted",
1615
- "Message Failed · Click to try again": "Message Failed · Click to try again",
1616
- "Message Failed · Unauthorized": "Message Failed · Unauthorized",
1617
1595
  "Message failed to send": "Message failed to send",
1618
1596
  "Message has been successfully flagged": "Message has been successfully flagged",
1619
1597
  "Message pinned": "Message pinned",
@@ -1783,6 +1761,7 @@ const enTranslations = {
1783
1761
  "View translation": "View translation",
1784
1762
  "Voice message": "Voice message",
1785
1763
  "Voice message {{ duration }}": "Voice message {{ duration }}",
1764
+ "Voice message deleted": "Voice message deleted",
1786
1765
  voiceMessageCount_one: voiceMessageCount_one$8,
1787
1766
  voiceMessageCount_other: voiceMessageCount_other$a,
1788
1767
  "Vote ended": "Vote ended",
@@ -2029,7 +2008,6 @@ const esTranslations = {
2029
2008
  "End vote": "Finalizar votación",
2030
2009
  "Enforce unique vote is enabled": "El voto único está habilitado",
2031
2010
  "Error": "Error",
2032
- "Error · Unsent": "Error · No enviado",
2033
2011
  "Error adding flag": "Error al agregar la bandera",
2034
2012
  "Error connecting to chat, refresh the page to try again.": "Error al conectarse al chat, actualice la página para volver a intentarlo.",
2035
2013
  "Error deleting message": "Error al eliminar el mensaje",
@@ -2154,8 +2132,6 @@ const esTranslations = {
2154
2132
  "Maximum number of votes (from 2 to 10)": "Número máximo de votos (de 2 a 10)",
2155
2133
  Menu: Menu$9,
2156
2134
  "Message deleted": "Mensaje eliminado",
2157
- "Message Failed · Click to try again": "Mensaje fallido · Haga clic para volver a intentarlo",
2158
- "Message Failed · Unauthorized": "Mensaje fallido · No autorizado",
2159
2135
  "Message failed to send": "No se pudo enviar el mensaje",
2160
2136
  "Message has been successfully flagged": "El mensaje se marcó correctamente",
2161
2137
  "Message pinned": "Mensaje fijado",
@@ -2332,6 +2308,7 @@ const esTranslations = {
2332
2308
  "View translation": "Ver traducción",
2333
2309
  "Voice message": "Mensaje de voz",
2334
2310
  "Voice message {{ duration }}": "Mensaje de voz {{ duration }}",
2311
+ "Voice message deleted": "Mensaje de voz eliminado",
2335
2312
  voiceMessageCount_one: voiceMessageCount_one$7,
2336
2313
  voiceMessageCount_many: voiceMessageCount_many$4,
2337
2314
  voiceMessageCount_other: voiceMessageCount_other$9,
@@ -2579,7 +2556,6 @@ const frTranslations = {
2579
2556
  "End vote": "Fin du vote",
2580
2557
  "Enforce unique vote is enabled": "Le vote unique est activé",
2581
2558
  "Error": "Erreur",
2582
- "Error · Unsent": "Erreur - Non envoyé",
2583
2559
  "Error adding flag": "Erreur lors de l'ajout du signalement",
2584
2560
  "Error connecting to chat, refresh the page to try again.": "Erreur de connexion au chat, rafraîchissez la page pour réessayer.",
2585
2561
  "Error deleting message": "Erreur lors de la suppression du message",
@@ -2704,8 +2680,6 @@ const frTranslations = {
2704
2680
  "Maximum number of votes (from 2 to 10)": "Nombre maximum de votes (de 2 à 10)",
2705
2681
  Menu: Menu$8,
2706
2682
  "Message deleted": "Message supprimé",
2707
- "Message Failed · Click to try again": "Échec de l'envoi du message - Cliquez pour réessayer",
2708
- "Message Failed · Unauthorized": "Échec de l'envoi du message - Non autorisé",
2709
2683
  "Message failed to send": "Échec de l'envoi du message",
2710
2684
  "Message has been successfully flagged": "Le message a été signalé avec succès",
2711
2685
  "Message pinned": "Message épinglé",
@@ -2882,6 +2856,7 @@ const frTranslations = {
2882
2856
  "View translation": "Voir la traduction",
2883
2857
  "Voice message": "Message vocal",
2884
2858
  "Voice message {{ duration }}": "Message vocal {{ duration }}",
2859
+ "Voice message deleted": "Message vocal supprimé",
2885
2860
  voiceMessageCount_one: voiceMessageCount_one$6,
2886
2861
  voiceMessageCount_many: voiceMessageCount_many$3,
2887
2862
  voiceMessageCount_other: voiceMessageCount_other$8,
@@ -3113,7 +3088,6 @@ const hiTranslations = {
3113
3088
  "End vote": "मत समाप्त करें",
3114
3089
  "Enforce unique vote is enabled": "अनोखा वोट सक्षम है",
3115
3090
  "Error": "त्रुटि",
3116
- "Error · Unsent": "फेल",
3117
3091
  "Error adding flag": "ध्वज जोड़ने में त्रुटि",
3118
3092
  "Error connecting to chat, refresh the page to try again.": "चैट से कनेक्ट करने में त्रुटि, पेज को रिफ्रेश करें",
3119
3093
  "Error deleting message": "संदेश हटाने में त्रुटि",
@@ -3236,8 +3210,6 @@ const hiTranslations = {
3236
3210
  "Maximum number of votes (from 2 to 10)": "अधिकतम वोटों की संख्या (2 से 10)",
3237
3211
  Menu: Menu$7,
3238
3212
  "Message deleted": "मैसेज हटा दिया गया",
3239
- "Message Failed · Click to try again": "मैसेज फ़ैल - पुनः कोशिश करें",
3240
- "Message Failed · Unauthorized": "मैसेज फ़ैल - अनधिकृत",
3241
3213
  "Message failed to send": "संदेश भेजने में विफल",
3242
3214
  "Message has been successfully flagged": "मैसेज को फ्लैग कर दिया गया है",
3243
3215
  "Message pinned": "संदेश पिन किया गया",
@@ -3407,6 +3379,7 @@ const hiTranslations = {
3407
3379
  "View translation": "अनुवाद देखें",
3408
3380
  "Voice message": "आवाज संदेश",
3409
3381
  "Voice message {{ duration }}": "वॉइस संदेश {{ duration }}",
3382
+ "Voice message deleted": "वॉइस संदेश हटा दिया गया",
3410
3383
  voiceMessageCount_one: voiceMessageCount_one$5,
3411
3384
  voiceMessageCount_other: voiceMessageCount_other$7,
3412
3385
  "Vote ended": "मतदान समाप्त",
@@ -3653,7 +3626,6 @@ const itTranslations = {
3653
3626
  "End vote": "Termina il voto",
3654
3627
  "Enforce unique vote is enabled": "Il voto unico è abilitato",
3655
3628
  "Error": "Errore",
3656
- "Error · Unsent": "Errore · Non inviato",
3657
3629
  "Error adding flag": "Errore durante l'aggiunta del flag",
3658
3630
  "Error connecting to chat, refresh the page to try again.": "Errore di connessione alla chat, aggiorna la pagina per riprovare.",
3659
3631
  "Error deleting message": "Errore durante l'eliminazione del messaggio",
@@ -3778,8 +3750,6 @@ const itTranslations = {
3778
3750
  "Maximum number of votes (from 2 to 10)": "Numero massimo di voti (da 2 a 10)",
3779
3751
  Menu: Menu$6,
3780
3752
  "Message deleted": "Messaggio cancellato",
3781
- "Message Failed · Click to try again": "Invio messaggio fallito · Clicca per riprovare",
3782
- "Message Failed · Unauthorized": "Invio messaggio fallito · Non autorizzato",
3783
3753
  "Message failed to send": "Invio del messaggio non riuscito",
3784
3754
  "Message has been successfully flagged": "Il messaggio è stato segnalato con successo",
3785
3755
  "Message pinned": "Messaggio bloccato",
@@ -3956,6 +3926,7 @@ const itTranslations = {
3956
3926
  "View translation": "Visualizza traduzione",
3957
3927
  "Voice message": "Messaggio vocale",
3958
3928
  "Voice message {{ duration }}": "Messaggio vocale {{ duration }}",
3929
+ "Voice message deleted": "Messaggio vocale eliminato",
3959
3930
  voiceMessageCount_one: voiceMessageCount_one$4,
3960
3931
  voiceMessageCount_many: voiceMessageCount_many$2,
3961
3932
  voiceMessageCount_other: voiceMessageCount_other$6,
@@ -4180,7 +4151,6 @@ const jaTranslations = {
4180
4151
  "End vote": "投票を終了",
4181
4152
  "Enforce unique vote is enabled": "一意の投票が有効になっています",
4182
4153
  "Error": "エラー",
4183
- "Error · Unsent": "エラー・未送信",
4184
4154
  "Error adding flag": "フラグを追加のエラーが発生しました",
4185
4155
  "Error connecting to chat, refresh the page to try again.": "チャットへの接続ができませんでした。ページを更新してください。",
4186
4156
  "Error deleting message": "メッセージを削除するエラーが発生しました",
@@ -4299,8 +4269,6 @@ const jaTranslations = {
4299
4269
  "Maximum number of votes (from 2 to 10)": "最大投票数(2から10まで)",
4300
4270
  Menu: Menu$5,
4301
4271
  "Message deleted": "メッセージが削除されました",
4302
- "Message Failed · Click to try again": "メッセージが失敗しました · クリックして再試行してください",
4303
- "Message Failed · Unauthorized": "メッセージが失敗しました · 許可されていません",
4304
4272
  "Message failed to send": "メッセージの送信に失敗しました",
4305
4273
  "Message has been successfully flagged": "メッセージに正常にフラグが付けられました",
4306
4274
  "Message pinned": "メッセージにピンが付けられました",
@@ -4467,6 +4435,7 @@ const jaTranslations = {
4467
4435
  "View translation": "翻訳を表示",
4468
4436
  "Voice message": "ボイスメッセージ",
4469
4437
  "Voice message {{ duration }}": "ボイスメッセージ {{ duration }}",
4438
+ "Voice message deleted": "ボイスメッセージが削除されました",
4470
4439
  voiceMessageCount_other: voiceMessageCount_other$5,
4471
4440
  "Vote ended": "投票が終了しました",
4472
4441
  Votes: Votes$5,
@@ -4689,7 +4658,6 @@ const koTranslations = {
4689
4658
  "End vote": "투표 종료",
4690
4659
  "Enforce unique vote is enabled": "고유 투표가 활성화되었습니다",
4691
4660
  "Error": "오류",
4692
- "Error · Unsent": "오류 · 전송되지 않음",
4693
4661
  "Error adding flag": "플래그를 추가하는 동안 오류가 발생했습니다.",
4694
4662
  "Error connecting to chat, refresh the page to try again.": "채팅에 연결하는 동안 오류가 발생했습니다. 페이지를 새로고침하여 다시 시도하세요.",
4695
4663
  "Error deleting message": "메시지를 삭제하는 중에 오류가 발생했습니다.",
@@ -4808,8 +4776,6 @@ const koTranslations = {
4808
4776
  "Maximum number of votes (from 2 to 10)": "최대 투표 수 (2에서 10까지)",
4809
4777
  Menu: Menu$4,
4810
4778
  "Message deleted": "메시지가 삭제되었습니다.",
4811
- "Message Failed · Click to try again": "메시지 실패 · 다시 시도하려면 클릭하세요.",
4812
- "Message Failed · Unauthorized": "메시지 실패 · 승인되지 않음",
4813
4779
  "Message failed to send": "메시지 전송 실패",
4814
4780
  "Message has been successfully flagged": "메시지에 플래그가 지정되었습니다.",
4815
4781
  "Message pinned": "메시지 핀했습니다",
@@ -4976,6 +4942,7 @@ const koTranslations = {
4976
4942
  "View translation": "번역 보기",
4977
4943
  "Voice message": "음성 메시지",
4978
4944
  "Voice message {{ duration }}": "음성 메시지 {{ duration }}",
4945
+ "Voice message deleted": "음성 메시지가 삭제됨",
4979
4946
  voiceMessageCount_other: voiceMessageCount_other$4,
4980
4947
  "Vote ended": "투표 종료",
4981
4948
  Votes: Votes$4,
@@ -5205,7 +5172,6 @@ const nlTranslations = {
5205
5172
  "End vote": "Einde stem",
5206
5173
  "Enforce unique vote is enabled": "Unieke stem is ingeschakeld",
5207
5174
  "Error": "Fout",
5208
- "Error · Unsent": "Fout · niet verzonden",
5209
5175
  "Error adding flag": "Fout bij toevoegen van vlag",
5210
5176
  "Error connecting to chat, refresh the page to try again.": "Fout bij het verbinden, ververs de pagina om nogmaals te proberen",
5211
5177
  "Error deleting message": "Fout bij verwijderen van bericht",
@@ -5327,8 +5293,6 @@ const nlTranslations = {
5327
5293
  "Maximum number of votes (from 2 to 10)": "Maximaal aantal stemmen (van 2 tot 10)",
5328
5294
  Menu: Menu$3,
5329
5295
  "Message deleted": "Bericht verwijderd",
5330
- "Message Failed · Click to try again": "Bericht mislukt, klik om het nogmaals te proberen",
5331
- "Message Failed · Unauthorized": "Bericht mislukt, ongeautoriseerd",
5332
5296
  "Message failed to send": "Bericht kon niet worden verzonden",
5333
5297
  "Message has been successfully flagged": "Bericht is succesvol gemarkeerd",
5334
5298
  "Message pinned": "Bericht vastgezet",
@@ -5500,6 +5464,7 @@ const nlTranslations = {
5500
5464
  "View translation": "Vertaling bekijken",
5501
5465
  "Voice message": "Spraakbericht",
5502
5466
  "Voice message {{ duration }}": "Spraakbericht {{ duration }}",
5467
+ "Voice message deleted": "Spraakbericht verwijderd",
5503
5468
  voiceMessageCount_one: voiceMessageCount_one$3,
5504
5469
  voiceMessageCount_other: voiceMessageCount_other$3,
5505
5470
  "Vote ended": "Stemmen beëindigd",
@@ -5746,7 +5711,6 @@ const ptTranslations = {
5746
5711
  "End vote": "Encerrar votação",
5747
5712
  "Enforce unique vote is enabled": "Voto único está habilitado",
5748
5713
  "Error": "Erro",
5749
- "Error · Unsent": "Erro · Não enviado",
5750
5714
  "Error adding flag": "Erro ao reportar",
5751
5715
  "Error connecting to chat, refresh the page to try again.": "Erro ao conectar ao bate-papo, atualize a página para tentar novamente.",
5752
5716
  "Error deleting message": "Erro ao deletar mensagem",
@@ -5871,8 +5835,6 @@ const ptTranslations = {
5871
5835
  "Maximum number of votes (from 2 to 10)": "Número máximo de votos (de 2 a 10)",
5872
5836
  Menu: Menu$2,
5873
5837
  "Message deleted": "Mensagem apagada",
5874
- "Message Failed · Click to try again": "A mensagem falhou · Clique para tentar novamente",
5875
- "Message Failed · Unauthorized": "A mensagem falhou · não autorizado",
5876
5838
  "Message failed to send": "Falha ao enviar a mensagem",
5877
5839
  "Message has been successfully flagged": "A mensagem foi reportada com sucesso",
5878
5840
  "Message pinned": "Mensagem fixada",
@@ -6049,6 +6011,7 @@ const ptTranslations = {
6049
6011
  "View translation": "Ver tradução",
6050
6012
  "Voice message": "Mensagem de voz",
6051
6013
  "Voice message {{ duration }}": "Mensagem de voz {{ duration }}",
6014
+ "Voice message deleted": "Mensagem de voz excluída",
6052
6015
  voiceMessageCount_one: voiceMessageCount_one$2,
6053
6016
  voiceMessageCount_many: voiceMessageCount_many$1,
6054
6017
  voiceMessageCount_other: voiceMessageCount_other$2,
@@ -6316,7 +6279,6 @@ const ruTranslations = {
6316
6279
  "End vote": "Закончить голосование",
6317
6280
  "Enforce unique vote is enabled": "Уникальное голосование включено",
6318
6281
  "Error": "Ошибка",
6319
- "Error · Unsent": "Ошибка · Не отправлено",
6320
6282
  "Error adding flag": "Ошибка добавления флага",
6321
6283
  "Error connecting to chat, refresh the page to try again.": "Ошибка подключения к чату, обновите страницу чтобы попробовать снова.",
6322
6284
  "Error deleting message": "Ошибка при удалении сообщения",
@@ -6447,8 +6409,6 @@ const ruTranslations = {
6447
6409
  "Maximum number of votes (from 2 to 10)": "Максимальное количество голосов (от 2 до 10)",
6448
6410
  Menu: Menu$1,
6449
6411
  "Message deleted": "Сообщение удалено",
6450
- "Message Failed · Click to try again": "Ошибка отправки сообщения · Нажмите чтобы повторить",
6451
- "Message Failed · Unauthorized": "Ошибка отправки сообщения · Неавторизованный",
6452
6412
  "Message failed to send": "Не удалось отправить сообщение",
6453
6413
  "Message has been successfully flagged": "Жалоба на сообщение была принята",
6454
6414
  "Message pinned": "Сообщение закреплено",
@@ -6632,6 +6592,7 @@ const ruTranslations = {
6632
6592
  "View translation": "Показать перевод",
6633
6593
  "Voice message": "Голосовое сообщение",
6634
6594
  "Voice message {{ duration }}": "Голосовое сообщение {{ duration }}",
6595
+ "Voice message deleted": "Голосовое сообщение удалено",
6635
6596
  voiceMessageCount_one: voiceMessageCount_one$1,
6636
6597
  voiceMessageCount_few,
6637
6598
  voiceMessageCount_many,
@@ -6864,7 +6825,6 @@ const trTranslations = {
6864
6825
  "End vote": "Oyu bitir",
6865
6826
  "Enforce unique vote is enabled": "Benzersiz oy etkinleştirildi",
6866
6827
  "Error": "Hata",
6867
- "Error · Unsent": "Hata · Gönderilemedi",
6868
6828
  "Error adding flag": "Bayrak eklenirken hata oluştu",
6869
6829
  "Error connecting to chat, refresh the page to try again.": "Bağlantı hatası, sayfayı yenileyip tekrar deneyin.",
6870
6830
  "Error deleting message": "Mesaj silinirken hata oluştu",
@@ -6986,8 +6946,6 @@ const trTranslations = {
6986
6946
  "Maximum number of votes (from 2 to 10)": "Maksimum oy sayısı (2 ile 10 arası)",
6987
6947
  Menu,
6988
6948
  "Message deleted": "Mesaj silindi",
6989
- "Message Failed · Click to try again": "Mesaj Başarısız · Tekrar denemek için tıklayın",
6990
- "Message Failed · Unauthorized": "Mesaj Başarısız · Yetkisiz",
6991
6949
  "Message failed to send": "Mesaj gönderilemedi",
6992
6950
  "Message has been successfully flagged": "Mesaj başarıyla bayraklandı",
6993
6951
  "Message pinned": "Mesaj sabitlendi",
@@ -7157,6 +7115,7 @@ const trTranslations = {
7157
7115
  "View translation": "Çeviriyi görüntüle",
7158
7116
  "Voice message": "Sesli mesaj",
7159
7117
  "Voice message {{ duration }}": "Sesli mesaj {{ duration }}",
7118
+ "Voice message deleted": "Sesli mesaj silindi",
7160
7119
  voiceMessageCount_one,
7161
7120
  voiceMessageCount_other,
7162
7121
  "Vote ended": "Oylama sona erdi",
@@ -8586,11 +8545,18 @@ function useActionHandler(message) {
8586
8545
  }
8587
8546
  const useDeleteHandler = (message, notifications = {}) => {
8588
8547
  const { getErrorNotification, notify } = notifications;
8589
- const { deleteMessage, updateMessage } = WithAudioPlayback.useChannelActionContext("useDeleteHandler");
8548
+ const { deleteMessage, removeMessage, updateMessage } = WithAudioPlayback.useChannelActionContext("useDeleteHandler");
8590
8549
  const { client } = WithAudioPlayback.useChatContext("useDeleteHandler");
8591
8550
  const { t } = WithAudioPlayback.useTranslationContext("useDeleteHandler");
8592
8551
  return async (options) => {
8593
- if (!message?.id || !client || !updateMessage) {
8552
+ if (!message) {
8553
+ return;
8554
+ }
8555
+ if (message.type === "error" || WithAudioPlayback.isNetworkSendFailure(message)) {
8556
+ removeMessage?.(message);
8557
+ return;
8558
+ }
8559
+ if (!message.id || !client || !updateMessage) {
8594
8560
  return;
8595
8561
  }
8596
8562
  try {
@@ -8599,6 +8565,7 @@ const useDeleteHandler = (message, notifications = {}) => {
8599
8565
  } catch (e) {
8600
8566
  const errorMessage = getErrorNotification && WithAudioPlayback.validateAndGetMessage(getErrorNotification, [message]);
8601
8567
  if (notify) notify(errorMessage || t("Error deleting message"), "error");
8568
+ throw e;
8602
8569
  }
8603
8570
  };
8604
8571
  };
@@ -8910,7 +8877,7 @@ const useUserRole = (message, onlySenderCanEdit, disableQuotedMessages) => {
8910
8877
  const canFlag = !isMyMessage && channelCapabilities["flag-message"];
8911
8878
  const canMute = !isMyMessage && channelCapabilities["mute-channel"];
8912
8879
  const canBlockUser = !isMyMessage;
8913
- const canMarkUnread = channelCapabilities["read-events"];
8880
+ const canMarkUnread = !isMyMessage && channelCapabilities["read-events"];
8914
8881
  const canQuote = !disableQuotedMessages && channelCapabilities["quote-message"];
8915
8882
  const canReact = channelCapabilities["send-reaction"];
8916
8883
  const canReply = channelCapabilities["send-reply"];
@@ -9007,73 +8974,6 @@ const useMessageReminder = (messageId) => {
9007
8974
  const { reminder } = WithAudioPlayback.useStateStore(client.reminders.state, reminderSelector);
9008
8975
  return reminder;
9009
8976
  };
9010
- const ActionsIcon = ({ className = "" }) => /* @__PURE__ */ jsxRuntime.jsx(
9011
- "svg",
9012
- {
9013
- className,
9014
- height: "4",
9015
- viewBox: "0 0 11 4",
9016
- width: "11",
9017
- xmlns: "http://www.w3.org/2000/svg",
9018
- children: /* @__PURE__ */ jsxRuntime.jsx(
9019
- "path",
9020
- {
9021
- d: "M1.5 3a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3zm4 0a1.5 1.5 0 1 1 0-3 1.5 1.5 0 0 1 0 3z",
9022
- fillRule: "nonzero"
9023
- }
9024
- )
9025
- }
9026
- );
9027
- const ReactionIcon = ({ className = "" }) => /* @__PURE__ */ jsxRuntime.jsx(
9028
- "svg",
9029
- {
9030
- className,
9031
- height: "12",
9032
- viewBox: "0 0 12 12",
9033
- width: "12",
9034
- xmlns: "http://www.w3.org/2000/svg",
9035
- children: /* @__PURE__ */ jsxRuntime.jsxs("g", { clipRule: "evenodd", fillRule: "evenodd", children: [
9036
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 1.2C3.3 1.2 1.2 3.3 1.2 6c0 2.7 2.1 4.8 4.8 4.8 2.7 0 4.8-2.1 4.8-4.8 0-2.7-2.1-4.8-4.8-4.8zM0 6c0-3.3 2.7-6 6-6s6 2.7 6 6-2.7 6-6 6-6-2.7-6-6z" }),
9037
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM8.4 4.5c0 .5-.4.9-.9.9s-.9-.4-.9-.9.4-.9.9-.9.9.4.9.9zM3.3 6.7c.3-.2.6-.1.8.1.3.4.8.9 1.5 1 .6.2 1.4.1 2.4-1 .2-.2.6-.3.8 0 .2.2.3.6 0 .8-1.1 1.3-2.4 1.7-3.5 1.5-1-.2-1.8-.9-2.2-1.5-.2-.3-.1-.7.2-.9z" })
9038
- ] })
9039
- }
9040
- );
9041
- const ThreadIcon = ({ className = "" }) => /* @__PURE__ */ jsxRuntime.jsx("svg", { className, height: "10", width: "14", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntime.jsx(
9042
- "path",
9043
- {
9044
- d: "M8.516 3c4.78 0 4.972 6.5 4.972 6.5-1.6-2.906-2.847-3.184-4.972-3.184v2.872L3.772 4.994 8.516.5V3zM.484 5l4.5-4.237v1.78L2.416 5l2.568 2.125v1.828L.484 5z",
9045
- fillRule: "evenodd"
9046
- }
9047
- ) });
9048
- const PinIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { height: "13", viewBox: "0 0 14 13", width: "14", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntime.jsx(
9049
- "path",
9050
- {
9051
- d: "M13.3518 6.686L6.75251 0.0866699L5.80984 1.02867L6.75318 1.972V1.97334L3.45318 5.272L3.45251 5.27334L2.50984 4.32934L1.56718 5.27267L4.39584 8.10067L0.624512 11.8713L1.56718 12.814L5.33851 9.04334L8.16718 11.8713L9.10984 10.9293L8.16718 9.986L11.4672 6.686L12.4098 7.62867L13.3518 6.686ZM7.22451 9.04267L7.22385 9.04334L4.39584 6.21467L7.69518 2.91467L10.5232 5.74267L7.22451 9.04267Z",
9052
- fillRule: "evenodd"
9053
- }
9054
- ) });
9055
- const MessageErrorIcon = () => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-error-icon", children: /* @__PURE__ */ jsxRuntime.jsxs(
9056
- "svg",
9057
- {
9058
- "data-testid": "error",
9059
- fill: "none",
9060
- height: "24",
9061
- viewBox: "0 0 24 24",
9062
- width: "24",
9063
- xmlns: "http://www.w3.org/2000/svg",
9064
- children: [
9065
- /* @__PURE__ */ jsxRuntime.jsx(
9066
- "path",
9067
- {
9068
- d: "M12 2C6.48 2 2 6.48 2 12C2 17.52 6.48 22 12 22C17.52 22 22 17.52 22 12C22 6.48 17.52 2 12 2Z",
9069
- fill: "black",
9070
- id: "background"
9071
- }
9072
- ),
9073
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M13 17H11V15H13V17ZM13 13H11V7H13V13Z", fill: "white" })
9074
- ]
9075
- }
9076
- ) });
9077
8977
  const Root = React.forwardRef(function AlertRoot({ children, className, ...props }, ref) {
9078
8978
  return /* @__PURE__ */ jsxRuntime.jsx("div", { ...props, className: clsx("str-chat__alert-root", className), ref, children });
9079
8979
  });
@@ -9334,6 +9234,11 @@ const Badge = ({
9334
9234
  children
9335
9235
  }
9336
9236
  );
9237
+ const ErrorBadge = ({
9238
+ className,
9239
+ size = "sm",
9240
+ ...rest
9241
+ }) => /* @__PURE__ */ jsxRuntime.jsx(Badge, { ...rest, className, size, variant: "error", children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconExclamation, {}) });
9337
9242
  function AvatarStack({
9338
9243
  badgeSize,
9339
9244
  component: Component = "div",
@@ -9858,9 +9763,9 @@ const GlobalModal = ({
9858
9763
  (source, event) => {
9859
9764
  const allow = onCloseAttempt?.(source, event);
9860
9765
  if (allow !== false) {
9861
- onClose?.(event);
9862
9766
  dialog.close();
9863
9767
  closingRef.current = true;
9768
+ onClose?.(event);
9864
9769
  }
9865
9770
  },
9866
9771
  [dialog, onClose, onCloseAttempt]
@@ -10036,6 +9941,7 @@ const useBaseMessageActionSetFilter = (messageActionSet, disable = false) => {
10036
9941
  const isMessageThreadReply = typeof message.parent_id === "string";
10037
9942
  const isBounced = WithAudioPlayback.isMessageBounced(message);
10038
9943
  const allowRetry = WithAudioPlayback.isMessageErrorRetryable(message);
9944
+ const hasNetworkSendFailure = WithAudioPlayback.isNetworkSendFailure(message);
10039
9945
  return React.useMemo(() => {
10040
9946
  if (disable) return messageActionSet;
10041
9947
  if (isBounced || isInitialMessage || // not sure whether this thing even works anymore
@@ -10045,7 +9951,7 @@ const useBaseMessageActionSetFilter = (messageActionSet, disable = false) => {
10045
9951
  if (WithAudioPlayback.ACTIONS_NOT_WORKING_IN_THREAD.includes(type) && isMessageThreadReply)
10046
9952
  return false;
10047
9953
  if (message.error) {
10048
- return type === "resendMessage" && canSendMessage && (allowRetry || isBounced) || type === "edit" && canEdit && isBounced || type === "delete" && canDelete && isBounced;
9954
+ return type === "resendMessage" && canSendMessage && (allowRetry || isBounced) || type === "edit" && (isBounced && canEdit || hasNetworkSendFailure) || type === "delete" && (isBounced && canDelete || hasNetworkSendFailure);
10049
9955
  }
10050
9956
  if (type === "resendMessage" || type === "blockUser" && !canBlockUser || type === "copyMessageText" && !message.text || type === "delete" && !canDelete || type === "edit" && !canEdit || type === "flag" && !canFlag || type === "markUnread" && !canMarkUnread || type === "mute" && !canMute || type === "quote" && !canQuote || type === "react" && !canReact || type === "reply" && !canReply || type === "remindMe" && !channelConfig?.["user_message_reminders"] || type === "saveForLater" && !channelConfig?.["user_message_reminders"])
10051
9957
  return false;
@@ -10072,6 +9978,7 @@ const useBaseMessageActionSetFilter = (messageActionSet, disable = false) => {
10072
9978
  message.text,
10073
9979
  message.type,
10074
9980
  disable,
9981
+ hasNetworkSendFailure,
10075
9982
  messageActionSet
10076
9983
  ]);
10077
9984
  };
@@ -10696,17 +10603,6 @@ const renderText = (text2, mentionedUsers, {
10696
10603
  }
10697
10604
  ) });
10698
10605
  };
10699
- const ROOT_CLASS_NAME = "str-chat__message--error-message";
10700
- function MessageErrorText({ message }) {
10701
- const { t } = WithAudioPlayback.useTranslationContext("MessageText");
10702
- if (message.type === "error" && !WithAudioPlayback.isMessageBounced(message)) {
10703
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ROOT_CLASS_NAME, children: t("Error · Unsent") });
10704
- }
10705
- if (message.status === "failed") {
10706
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: ROOT_CLASS_NAME, children: message.error?.status !== 403 ? t("Message Failed · Click to try again") : t("Message Failed · Unauthorized") });
10707
- }
10708
- return null;
10709
- }
10710
10606
  const UnMemoizedMessageTextComponent = (props) => {
10711
10607
  const {
10712
10608
  customInnerClass,
@@ -10734,7 +10630,7 @@ const UnMemoizedMessageTextComponent = (props) => {
10734
10630
  const wrapperClass = customWrapperClass || "str-chat__message-text";
10735
10631
  const innerClass = customInnerClass;
10736
10632
  if (!messageTextToRender) return null;
10737
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClass, tabIndex: 0, children: /* @__PURE__ */ jsxRuntime.jsxs(
10633
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClass, tabIndex: 0, children: /* @__PURE__ */ jsxRuntime.jsx(
10738
10634
  "div",
10739
10635
  {
10740
10636
  className: clsx(innerClass, {
@@ -10744,10 +10640,7 @@ const UnMemoizedMessageTextComponent = (props) => {
10744
10640
  "data-testid": "message-text-inner-wrapper",
10745
10641
  onClick: onMentionsClickMessage,
10746
10642
  onMouseOver: onMentionsHoverMessage,
10747
- children: [
10748
- /* @__PURE__ */ jsxRuntime.jsx(MessageErrorText, { message }),
10749
- unsafeHTML && message.html ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: message.html } }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: messageText })
10750
- ]
10643
+ children: unsafeHTML && message.html ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: message.html } }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: messageText })
10751
10644
  }
10752
10645
  ) });
10753
10646
  };
@@ -15093,10 +14986,12 @@ const PollOptionSelector = ({
15093
14986
  canCastVote && /* @__PURE__ */ jsxRuntime.jsx(Checkmark, { checked: !!ownVotesByOptionId[option.id] }),
15094
14987
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__poll-option-data", children: [
15095
14988
  /* @__PURE__ */ jsxRuntime.jsx("p", { className: "str-chat__poll-option-text", children: option.text }),
15096
- displayAvatarCount && voting_visibility === "public" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__poll-option-voters", children: /* @__PURE__ */ jsxRuntime.jsx(AvatarStack$1, { displayInfo: avatarDisplayInfo, size: "xs" }) }),
15097
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__poll-option-vote-count", children: voteCountVerbose ? t("{{count}} votes", {
15098
- count: vote_counts_by_option[option.id] ?? 0
15099
- }) : vote_counts_by_option[option.id] ?? 0 })
14989
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__poll-option-votes", children: [
14990
+ displayAvatarCount && voting_visibility === "public" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__poll-option-voters", children: /* @__PURE__ */ jsxRuntime.jsx(AvatarStack$1, { displayInfo: avatarDisplayInfo, size: "xs" }) }),
14991
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__poll-option-vote-count", children: voteCountVerbose ? t("{{count}} votes", {
14992
+ count: vote_counts_by_option[option.id] ?? 0
14993
+ }) : vote_counts_by_option[option.id] ?? 0 })
14994
+ ] })
15100
14995
  ] }),
15101
14996
  /* @__PURE__ */ jsxRuntime.jsx(
15102
14997
  AmountBar,
@@ -15611,31 +15506,34 @@ const CommandContextMenuItem = ({
15611
15506
  }
15612
15507
  );
15613
15508
  };
15614
- const AttachmentSelectorMenuInitButtonIcon = () => {
15509
+ const AttachmentSelectorMenuInitButtonIcon = ({ className }) => {
15615
15510
  const { AttachmentSelectorInitiationButtonContents } = WithAudioPlayback.useComponentContext();
15616
15511
  if (AttachmentSelectorInitiationButtonContents) {
15617
- return /* @__PURE__ */ jsxRuntime.jsx(AttachmentSelectorInitiationButtonContents, {});
15512
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { className, children: /* @__PURE__ */ jsxRuntime.jsx(AttachmentSelectorInitiationButtonContents, {}) });
15618
15513
  }
15619
- return /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconPlusLarge, { className: "str-chat__attachment-selector__menu-button__icon" });
15514
+ return /* @__PURE__ */ jsxRuntime.jsx(
15515
+ WithAudioPlayback.IconPlusLarge,
15516
+ {
15517
+ className: clsx("str-chat__attachment-selector__menu-button__icon", className)
15518
+ }
15519
+ );
15620
15520
  };
15621
- const AttachmentSelectorButton = React.forwardRef(
15622
- function AttachmentSelectorButton2({ className, ...props }, ref) {
15623
- return /* @__PURE__ */ jsxRuntime.jsx(
15624
- WithAudioPlayback.Button,
15625
- {
15626
- appearance: "outline",
15627
- circular: true,
15628
- className: clsx("str-chat__attachment-selector__menu-button", className),
15629
- "data-testid": "invoke-attachment-selector-button",
15630
- size: "lg",
15631
- variant: "secondary",
15632
- ...props,
15633
- ref,
15634
- children: /* @__PURE__ */ jsxRuntime.jsx(AttachmentSelectorMenuInitButtonIcon, {})
15635
- }
15636
- );
15637
- }
15638
- );
15521
+ const AttachmentSelectorButton = React.forwardRef(function AttachmentSelectorButton2({ className, iconClassName, ...props }, ref) {
15522
+ return /* @__PURE__ */ jsxRuntime.jsx(
15523
+ WithAudioPlayback.Button,
15524
+ {
15525
+ appearance: "outline",
15526
+ circular: true,
15527
+ className: clsx("str-chat__attachment-selector__menu-button", className),
15528
+ "data-testid": "invoke-attachment-selector-button",
15529
+ size: "lg",
15530
+ variant: "secondary",
15531
+ ...props,
15532
+ ref,
15533
+ children: /* @__PURE__ */ jsxRuntime.jsx(AttachmentSelectorMenuInitButtonIcon, { className: iconClassName })
15534
+ }
15535
+ );
15536
+ });
15639
15537
  const SimpleAttachmentSelector = () => {
15640
15538
  const { channelCapabilities } = WithAudioPlayback.useChannelStateContext();
15641
15539
  const inputRef = React.useRef(null);
@@ -15858,10 +15756,10 @@ const AttachmentSelector = ({
15858
15756
  "aria-expanded": menuDialogIsOpen,
15859
15757
  "aria-haspopup": "true",
15860
15758
  "aria-label": t("aria/Open Attachment Selector"),
15861
- className: clsx("str-chat__prepare-rotate45", {
15759
+ disabled: isCooldownActive,
15760
+ iconClassName: clsx("str-chat__prepare-rotate45", {
15862
15761
  "str-chat__rotate45": menuDialogIsOpen
15863
15762
  }),
15864
- disabled: isCooldownActive,
15865
15763
  onClick: () => menuDialog?.toggle(),
15866
15764
  ref: menuButtonRef
15867
15765
  }
@@ -15986,449 +15884,62 @@ const PlayIcon = () => /* @__PURE__ */ jsxRuntime.jsx(
15986
15884
  }
15987
15885
  );
15988
15886
  const CheckSignIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { fill: "currentColor", viewBox: "0 0 18 14", xmlns: "http://www.w3.org/2000/svg", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.79457 10.875L2.32457 7.40502C1.93457 7.01502 1.30457 7.01502 0.91457 7.40502C0.52457 7.79502 0.52457 8.42502 0.91457 8.81502L5.09457 12.995C5.48457 13.385 6.11457 13.385 6.50457 12.995L17.0846 2.41502C17.4746 2.02502 17.4746 1.39502 17.0846 1.00502C16.6946 0.615024 16.0646 0.615024 15.6746 1.00502L5.79457 10.875Z" }) });
15989
- const toGalleryItemDescriptors = (...args) => toBaseImageDescriptors(...args);
15990
- const GalleryContext = React.createContext(void 0);
15991
- const useGalleryContext = () => {
15992
- const contextValue = React.useContext(GalleryContext);
15993
- if (!contextValue) {
15994
- console.warn(
15995
- `The useGalleryContext hook was called outside of the GalleryContext provider. Make sure this hook is called within a child of the Gallery component.`
15996
- );
15997
- return {};
15887
+ const INTERACTIVE_SELECTOR = 'button, a, input, textarea, select, [role="button"], [role="link"], [data-interactive="true"]';
15888
+ function hasInteractiveAncestorBeforeRoot(target, root) {
15889
+ if (!(target instanceof Element) || !root) return false;
15890
+ let el = target;
15891
+ while (el && el !== root) {
15892
+ if (el.matches(INTERACTIVE_SELECTOR)) return true;
15893
+ el = el.parentElement;
15998
15894
  }
15999
- return contextValue;
16000
- };
16001
- const Gallery = ({
16002
- closeOnBackgroundClick = true,
16003
- GalleryUI: GalleryUI2,
16004
- initialIndex = 0,
16005
- items,
16006
- onIndexChange,
16007
- onRequestClose
15895
+ return false;
15896
+ }
15897
+ const AttachmentPreviewRoot = ({
15898
+ attachment,
15899
+ onPressed,
15900
+ openPreview,
15901
+ tabIndex = 0,
15902
+ ...props
16008
15903
  }) => {
16009
- const [currentIndex, setCurrentIndex] = React.useState(initialIndex);
16010
- const itemCount = items.length;
16011
- const goToIndex = React.useCallback(
16012
- (index) => {
16013
- if (index >= 0 && index < itemCount) {
16014
- setCurrentIndex(index);
16015
- }
16016
- },
16017
- [itemCount]
16018
- );
16019
- const goToNext = React.useCallback(() => {
16020
- setCurrentIndex((prev) => prev < itemCount - 1 ? prev + 1 : prev);
16021
- }, [itemCount]);
16022
- const goToPrevious = React.useCallback(() => {
16023
- setCurrentIndex((prev) => prev > 0 ? prev - 1 : prev);
16024
- }, []);
16025
- React.useEffect(() => {
16026
- onIndexChange?.(currentIndex);
16027
- }, [currentIndex, onIndexChange]);
16028
- const hasNext = currentIndex < itemCount - 1;
16029
- const hasPrevious = currentIndex > 0;
16030
- const currentItem = items[currentIndex];
16031
- const contextValue = React.useMemo(
16032
- () => ({
16033
- closeOnBackgroundClick,
16034
- currentIndex,
16035
- currentItem,
16036
- goToIndex,
16037
- goToNext,
16038
- goToPrevious,
16039
- hasNext,
16040
- hasPrevious,
16041
- itemCount,
16042
- items,
16043
- onRequestClose
16044
- }),
16045
- [
16046
- closeOnBackgroundClick,
16047
- currentIndex,
16048
- currentItem,
16049
- goToIndex,
16050
- goToNext,
16051
- goToPrevious,
16052
- hasNext,
16053
- hasPrevious,
16054
- itemCount,
16055
- items,
16056
- onRequestClose
16057
- ]
16058
- );
16059
- return /* @__PURE__ */ jsxRuntime.jsx(GalleryContext.Provider, { value: contextValue, children: GalleryUI2 ? /* @__PURE__ */ jsxRuntime.jsx(GalleryUI2, {}) : null });
16060
- };
16061
- const GalleryHeader = ({ currentItem }) => {
16062
15904
  const { t } = WithAudioPlayback.useTranslationContext();
16063
- const { MessageTimestamp: MessageTimestamp$1 = MessageTimestamp } = WithAudioPlayback.useComponentContext();
16064
- const { isMyMessage, message } = useMessageContext();
16065
- const modalContext = React.useContext(ModalContext);
16066
- const headerTitle = isMyMessage?.() && t("You") || message?.user?.name || message?.user?.id || currentItem.title || t("User uploaded content");
16067
- const downloadUrl = React.useMemo(() => {
16068
- const rawDownloadUrl = currentItem.videoUrl ?? currentItem.imageUrl;
16069
- if (!rawDownloadUrl) return void 0;
16070
- const sanitizedUrl = sanitizeUrl.sanitizeUrl(rawDownloadUrl);
16071
- return sanitizedUrl === "about:blank" ? void 0 : sanitizedUrl;
16072
- }, [currentItem.imageUrl, currentItem.videoUrl]);
16073
- const downloadLabel = t("aria/Download attachment");
16074
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__header", children: [
16075
- /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", className: "str-chat__gallery__header-spacer" }),
16076
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__header-meta", children: [
16077
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__gallery__title", children: headerTitle }),
16078
- message?.created_at ? /* @__PURE__ */ jsxRuntime.jsx(MessageTimestamp$1, { customClass: "str-chat__gallery__timestamp" }) : null
16079
- ] }),
16080
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__header-actions", children: [
16081
- downloadUrl ? /* @__PURE__ */ jsxRuntime.jsx(
16082
- "a",
16083
- {
16084
- "aria-label": downloadLabel,
16085
- className: "str-chat__gallery__action-button str-chat__gallery__action-button--download",
16086
- download: true,
16087
- href: downloadUrl,
16088
- rel: "noreferrer",
16089
- target: "_blank",
16090
- title: downloadLabel,
16091
- children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconArrowDownCircle, {})
16092
- }
16093
- ) : null,
16094
- modalContext?.close ? /* @__PURE__ */ jsxRuntime.jsx(
16095
- WithAudioPlayback.Button,
16096
- {
16097
- "aria-label": t("Close"),
16098
- className: "str-chat__gallery__action-button str-chat__gallery__action-button--close",
16099
- onClick: modalContext.close,
16100
- title: t("Close"),
16101
- children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconCrossMedium, {})
16102
- }
16103
- ) : null
16104
- ] })
16105
- ] });
16106
- };
16107
- const VideoPlayer = ({ isPlaying, thumbnailUrl, videoUrl }) => {
16108
- const { VideoPlayer: VideoPlayerContext } = WithAudioPlayback.useComponentContext();
16109
- return VideoPlayerContext ? /* @__PURE__ */ jsxRuntime.jsx(VideoPlayerContext, { thumbnailUrl, videoUrl }) : /* @__PURE__ */ jsxRuntime.jsx(
16110
- ReactPlayer,
16111
- {
16112
- className: "react-player",
16113
- config: { file: { attributes: { poster: thumbnailUrl } } },
16114
- controls: true,
16115
- height: "100%",
16116
- playing: isPlaying,
16117
- url: videoUrl,
16118
- width: "100%"
15905
+ const [root, setRoot] = React.useState(null);
15906
+ const url = attachment.asset_url || attachment.image_url || attachment.localMetadata.previewUri;
15907
+ const canDownloadAttachment = false;
15908
+ const canPreviewAttachment = !!openPreview && (!!url && streamChat.isImageAttachment(attachment) || streamChat.isVideoAttachment(attachment));
15909
+ const handlePressed = (e) => {
15910
+ if (e.defaultPrevented) return;
15911
+ if (hasInteractiveAncestorBeforeRoot(e.target, root)) return;
15912
+ if (onPressed) {
15913
+ const shouldContinue = onPressed(e);
15914
+ if (!shouldContinue) return;
16119
15915
  }
16120
- );
16121
- };
16122
- const VideoThumbnail = ({
16123
- className,
16124
- onPlay,
16125
- ...imageProps
16126
- }) => {
16127
- const { t } = WithAudioPlayback.useTranslationContext();
16128
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-attachment__video-thumbnail", children: [
16129
- /* @__PURE__ */ jsxRuntime.jsx(
16130
- BaseImage,
16131
- {
16132
- className: clsx("str-chat__message-attachment__video-thumbnail-image", className),
16133
- ...imageProps
16134
- }
16135
- ),
16136
- onPlay ? /* @__PURE__ */ jsxRuntime.jsx(
16137
- WithAudioPlayback.Button,
16138
- {
16139
- appearance: "solid",
16140
- "aria-label": t("Play video"),
16141
- circular: true,
16142
- className: clsx(
16143
- "str-chat__message-attachment__video-thumbnail__play-indicator"
16144
- ),
16145
- onClick: onPlay,
16146
- size: "lg",
16147
- variant: "secondary",
16148
- children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconPlaySolid, {})
16149
- }
16150
- ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-attachment__video-thumbnail__play-indicator", children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconPlaySolid, {}) })
16151
- ] });
16152
- };
16153
- const SWIPE_THRESHOLD = 50;
16154
- const TRANSITION_DURATION = 300;
16155
- const GalleryUI = () => {
16156
- const { t } = WithAudioPlayback.useTranslationContext();
16157
- const {
16158
- closeOnBackgroundClick,
16159
- currentIndex,
16160
- currentItem,
16161
- goToNext,
16162
- goToPrevious,
16163
- hasNext,
16164
- hasPrevious,
16165
- itemCount,
16166
- onRequestClose
16167
- } = useGalleryContext();
16168
- const modalContext = React.useContext(ModalContext);
16169
- const [showVideo, setShowVideo] = React.useState(false);
16170
- const isTransitioningRef = React.useRef(false);
16171
- const [slideOffset, setSlideOffset] = React.useState(0);
16172
- const [isDragging, setIsDragging] = React.useState(false);
16173
- const [slideDirection, setSlideDirection] = React.useState(
16174
- null
16175
- );
16176
- const ignoreNextClickRef = React.useRef(false);
16177
- const touchStartRef = React.useRef(null);
16178
- const isVerticalSwipeRef = React.useRef(false);
16179
- const containerRef = React.useRef(null);
16180
- React.useEffect(() => {
16181
- setShowVideo(false);
16182
- }, [currentIndex]);
16183
- const prevIndexRef = React.useRef(currentIndex);
16184
- React.useEffect(() => {
16185
- if (prevIndexRef.current === currentIndex) return;
16186
- const direction = currentIndex > prevIndexRef.current ? "forward" : "backward";
16187
- setSlideDirection(direction);
16188
- setSlideOffset(0);
16189
- setIsDragging(false);
16190
- isTransitioningRef.current = true;
16191
- const timer = setTimeout(() => {
16192
- setSlideDirection(null);
16193
- isTransitioningRef.current = false;
16194
- }, TRANSITION_DURATION);
16195
- prevIndexRef.current = currentIndex;
16196
- return () => clearTimeout(timer);
16197
- }, [currentIndex]);
16198
- const handleGoToNext = React.useCallback(() => {
16199
- if (isTransitioningRef.current) return;
16200
- goToNext();
16201
- }, [goToNext]);
16202
- const handleGoToPrevious = React.useCallback(() => {
16203
- if (isTransitioningRef.current) return;
16204
- goToPrevious();
16205
- }, [goToPrevious]);
16206
- const handleKeyDown = React.useCallback(
16207
- (event) => {
16208
- if (event.key === "ArrowLeft") {
16209
- event.preventDefault();
16210
- handleGoToPrevious();
16211
- } else if (event.key === "ArrowRight") {
16212
- event.preventDefault();
16213
- handleGoToNext();
16214
- }
16215
- },
16216
- [handleGoToNext, handleGoToPrevious]
16217
- );
16218
- React.useEffect(() => {
16219
- document.addEventListener("keydown", handleKeyDown);
16220
- return () => document.removeEventListener("keydown", handleKeyDown);
16221
- }, [handleKeyDown]);
16222
- const handleTouchStart = React.useCallback((event) => {
16223
- if (isTransitioningRef.current) return;
16224
- const touch = event.touches[0];
16225
- ignoreNextClickRef.current = false;
16226
- touchStartRef.current = { x: touch.clientX, y: touch.clientY };
16227
- isVerticalSwipeRef.current = false;
16228
- }, []);
16229
- const handleTouchMove = React.useCallback(
16230
- (event) => {
16231
- if (!touchStartRef.current || isTransitioningRef.current) return;
16232
- const touch = event.touches[0];
16233
- const deltaX = touch.clientX - touchStartRef.current.x;
16234
- const deltaY = touch.clientY - touchStartRef.current.y;
16235
- if (!isDragging && !isVerticalSwipeRef.current) {
16236
- if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > 10) {
16237
- ignoreNextClickRef.current = true;
16238
- isVerticalSwipeRef.current = true;
16239
- return;
16240
- }
16241
- if (Math.abs(deltaX) > 10) {
16242
- ignoreNextClickRef.current = true;
16243
- setIsDragging(true);
16244
- }
16245
- }
16246
- if (isVerticalSwipeRef.current) return;
16247
- if (!hasNext && deltaX < 0 || !hasPrevious && deltaX > 0) {
16248
- setSlideOffset(deltaX * 0.3);
16249
- } else {
16250
- setSlideOffset(deltaX);
16251
- }
16252
- },
16253
- [isDragging, hasNext, hasPrevious]
16254
- );
16255
- const handleTouchEnd = React.useCallback(() => {
16256
- if (!touchStartRef.current || isVerticalSwipeRef.current) {
16257
- if (isVerticalSwipeRef.current) ignoreNextClickRef.current = true;
16258
- touchStartRef.current = null;
15916
+ if (canPreviewAttachment) {
15917
+ openPreview();
16259
15918
  return;
16260
15919
  }
16261
- const offset = slideOffset;
16262
- if (isDragging || Math.abs(offset) > 10) {
16263
- ignoreNextClickRef.current = true;
16264
- }
16265
- touchStartRef.current = null;
16266
- if (Math.abs(offset) >= SWIPE_THRESHOLD) {
16267
- if (offset < 0 && hasNext) {
16268
- goToNext();
16269
- } else if (offset > 0 && hasPrevious) {
16270
- goToPrevious();
16271
- } else {
16272
- setSlideOffset(0);
16273
- }
16274
- } else {
16275
- setSlideOffset(0);
15920
+ };
15921
+ const isInteractive = canPreviewAttachment || canDownloadAttachment;
15922
+ return /* @__PURE__ */ jsxRuntime.jsx(
15923
+ "div",
15924
+ {
15925
+ "aria-label": isInteractive ? t(canPreviewAttachment ? "aria/Show preview" : "aria/Download attachment") : void 0,
15926
+ ...props,
15927
+ onClick: handlePressed,
15928
+ onKeyDown: isInteractive ? (e) => {
15929
+ if (e.key !== "Enter" && e.key !== " ") return;
15930
+ e.preventDefault();
15931
+ handlePressed(e);
15932
+ } : void 0,
15933
+ ref: setRoot,
15934
+ tabIndex: isInteractive ? tabIndex : -1,
15935
+ children: props.children
16276
15936
  }
16277
- setIsDragging(false);
16278
- }, [slideOffset, hasNext, hasPrevious, goToNext, goToPrevious, isDragging]);
16279
- const requestClose = modalContext?.close ?? onRequestClose;
16280
- const handleBackgroundClick = React.useCallback(
16281
- (event) => {
16282
- if (event.target !== event.currentTarget) return;
16283
- if (ignoreNextClickRef.current) {
16284
- ignoreNextClickRef.current = false;
16285
- return;
16286
- }
16287
- if (!closeOnBackgroundClick) return;
16288
- requestClose?.();
16289
- },
16290
- [closeOnBackgroundClick, requestClose]
16291
15937
  );
16292
- const mediaStyle = isDragging || slideOffset !== 0 && slideDirection === null ? { transform: `translateX(${slideOffset}px)` } : {};
16293
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery", children: [
16294
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__main", children: [
16295
- /* @__PURE__ */ jsxRuntime.jsx(GalleryHeader, { currentItem }),
16296
- /* @__PURE__ */ jsxRuntime.jsx(
16297
- NavButton,
16298
- {
16299
- "aria-label": t("Previous image"),
16300
- className: clsx(
16301
- "str-chat__gallery__nav-button--prev",
16302
- !hasPrevious && "str-chat__gallery__nav-button--hidden"
16303
- ),
16304
- disabled: !hasPrevious,
16305
- onClick: handleGoToPrevious,
16306
- children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconChevronLeft, {})
16307
- }
16308
- ),
16309
- /* @__PURE__ */ jsxRuntime.jsx(
16310
- "div",
16311
- {
16312
- className: "str-chat__gallery__slide-container",
16313
- onClick: handleBackgroundClick,
16314
- onTouchEnd: handleTouchEnd,
16315
- onTouchMove: handleTouchMove,
16316
- onTouchStart: handleTouchStart,
16317
- ref: containerRef,
16318
- children: /* @__PURE__ */ jsxRuntime.jsx(
16319
- "div",
16320
- {
16321
- className: clsx({
16322
- "str-chat__gallery__media--dragging": isDragging,
16323
- "str-chat__gallery__media--slide-backward": !isDragging && slideDirection === "backward",
16324
- "str-chat__gallery__media--slide-forward": !isDragging && slideDirection === "forward"
16325
- }),
16326
- style: mediaStyle,
16327
- children: currentItem.videoUrl && currentItem.videoThumbnailUrl ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__gallery__media str-chat__gallery__media--video", children: showVideo ? /* @__PURE__ */ jsxRuntime.jsx(VideoPlayer, { isPlaying: true, videoUrl: currentItem.videoUrl }) : /* @__PURE__ */ jsxRuntime.jsx(
16328
- VideoThumbnail,
16329
- {
16330
- alt: currentItem.title ?? "",
16331
- onPlay: () => setShowVideo(true),
16332
- src: currentItem.videoThumbnailUrl
16333
- }
16334
- ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__gallery__media str-chat__gallery__media--image", children: /* @__PURE__ */ jsxRuntime.jsx(BaseImage, { alt: currentItem.alt, src: currentItem.imageUrl }) })
16335
- }
16336
- )
16337
- }
16338
- ),
16339
- /* @__PURE__ */ jsxRuntime.jsx(
16340
- NavButton,
16341
- {
16342
- "aria-label": t("Next image"),
16343
- className: clsx(
16344
- "str-chat__gallery__nav-button--next",
16345
- !hasNext && "str-chat__gallery__nav-button--hidden"
16346
- ),
16347
- disabled: !hasNext,
16348
- onClick: handleGoToNext,
16349
- children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconChevronRight, {})
16350
- }
16351
- )
16352
- ] }),
16353
- itemCount > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__position-indicator", children: [
16354
- currentIndex + 1,
16355
- " of ",
16356
- itemCount
16357
- ] })
16358
- ] });
16359
15938
  };
16360
- const NavButton = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.Button, { ...props, className: clsx("str-chat__gallery__nav-button", className) });
16361
- const INTERACTIVE_SELECTOR = 'button, a, input, textarea, select, [role="button"], [role="link"], [data-interactive="true"]';
16362
- function hasInteractiveAncestorBeforeRoot(target, root) {
16363
- if (!(target instanceof Element) || !root) return false;
16364
- let el = target;
16365
- while (el && el !== root) {
16366
- if (el.matches(INTERACTIVE_SELECTOR)) return true;
16367
- el = el.parentElement;
16368
- }
16369
- return false;
16370
- }
16371
- const AttachmentPreviewRoot = ({
15939
+ const FileAttachmentPreview = ({
16372
15940
  attachment,
16373
- onPressed,
16374
- tabIndex = 0,
16375
- ...props
16376
- }) => {
16377
- const { t } = WithAudioPlayback.useTranslationContext("FilePreview");
16378
- const { Modal = GlobalModal } = WithAudioPlayback.useComponentContext();
16379
- const [showPreview, setShowPreview] = React.useState(false);
16380
- const [root, setRoot] = React.useState(null);
16381
- const url = attachment.asset_url || attachment.image_url || attachment.localMetadata.previewUri;
16382
- const canDownloadAttachment = false;
16383
- const canPreviewAttachment = !!url && streamChat.isImageAttachment(attachment) || streamChat.isVideoAttachment(attachment);
16384
- const handlePressed = (e) => {
16385
- if (e.defaultPrevented) return;
16386
- if (hasInteractiveAncestorBeforeRoot(e.target, root)) return;
16387
- if (onPressed) {
16388
- const shouldContinue = onPressed(e);
16389
- if (!shouldContinue) return;
16390
- }
16391
- if (canPreviewAttachment) {
16392
- setShowPreview(true);
16393
- return;
16394
- }
16395
- };
16396
- return /* @__PURE__ */ jsxRuntime.jsxs(
16397
- "div",
16398
- {
16399
- "aria-label": t(showPreview ? "aria/Show preview" : "aria/Download attachment"),
16400
- ...props,
16401
- onClick: handlePressed,
16402
- onKeyDown: (e) => {
16403
- if (e.key !== "Enter" && e.key !== " ") return;
16404
- e.preventDefault();
16405
- handlePressed(e);
16406
- },
16407
- ref: setRoot,
16408
- role: showPreview ? "button" : props.role,
16409
- tabIndex: showPreview || canDownloadAttachment ? tabIndex : -1,
16410
- children: [
16411
- props.children,
16412
- /* @__PURE__ */ jsxRuntime.jsx(
16413
- Modal,
16414
- {
16415
- className: "str-chat__gallery-modal",
16416
- onClose: (e) => {
16417
- e.stopPropagation();
16418
- setShowPreview(false);
16419
- },
16420
- open: showPreview && canPreviewAttachment,
16421
- children: streamChat.isImageAttachment(attachment) || streamChat.isVideoAttachment(attachment) ? /* @__PURE__ */ jsxRuntime.jsx(Gallery, { items: [attachment] }) : null
16422
- }
16423
- )
16424
- ]
16425
- }
16426
- );
16427
- };
16428
- const FileAttachmentPreview = ({
16429
- attachment,
16430
- handleRetry,
16431
- removeAttachments
15941
+ handleRetry,
15942
+ removeAttachments
16432
15943
  }) => {
16433
15944
  const { t } = WithAudioPlayback.useTranslationContext("FilePreview");
16434
15945
  const { id, uploadPermissionCheck, uploadState } = attachment.localMetadata ?? {};
@@ -17048,6 +16559,7 @@ const AudioAttachmentPreview = ({
17048
16559
  const MediaAttachmentPreview = ({
17049
16560
  attachment,
17050
16561
  handleRetry,
16562
+ openPreview,
17051
16563
  removeAttachments
17052
16564
  }) => {
17053
16565
  const { t } = WithAudioPlayback.useTranslationContext();
@@ -17077,65 +16589,440 @@ const MediaAttachmentPreview = ({
17077
16589
  },
17078
16590
  [attachment]
17079
16591
  );
17080
- return /* @__PURE__ */ jsxRuntime.jsxs(
17081
- AttachmentPreviewRoot,
17082
- {
17083
- attachment,
17084
- className: clsx("str-chat__attachment-preview-media", {
17085
- "str-chat__attachment-preview-media--thumbnail-preview-error": thumbnailPreviewError,
17086
- "str-chat__attachment-preview-media--upload-error": hasUploadError,
17087
- "str-chat__attachment-preview-media--uploading": isUploading
17088
- }),
17089
- "data-testid": "attachment-preview-media",
17090
- onPressed: hasRetriableError ? retry : void 0,
17091
- children: [
17092
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__attachment-preview-media__thumbnail-wrapper", children: [
17093
- thumbnail.url && /* @__PURE__ */ jsxRuntime.jsx(
17094
- BaseImage$1,
16592
+ return /* @__PURE__ */ jsxRuntime.jsxs(
16593
+ AttachmentPreviewRoot,
16594
+ {
16595
+ attachment,
16596
+ className: clsx("str-chat__attachment-preview-media", {
16597
+ "str-chat__attachment-preview-media--thumbnail-preview-error": thumbnailPreviewError,
16598
+ "str-chat__attachment-preview-media--upload-error": hasUploadError,
16599
+ "str-chat__attachment-preview-media--uploading": isUploading
16600
+ }),
16601
+ "data-testid": "attachment-preview-media",
16602
+ onPressed: hasRetriableError ? retry : void 0,
16603
+ openPreview: !isUploading && !hasUploadError ? openPreview : void 0,
16604
+ children: [
16605
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__attachment-preview-media__thumbnail-wrapper", children: [
16606
+ thumbnail.url && /* @__PURE__ */ jsxRuntime.jsx(
16607
+ BaseImage$1,
16608
+ {
16609
+ alt: thumbnail.alt,
16610
+ className: "str-chat__attachment-preview-media__thumbnail",
16611
+ onError: handleThumbnailLoadError,
16612
+ src: thumbnail.url,
16613
+ title: thumbnail.title
16614
+ }
16615
+ ),
16616
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("str-chat__attachment-preview-media__overlay"), children: [
16617
+ isUploading && /* @__PURE__ */ jsxRuntime.jsx(LoadingIndicator2, {}),
16618
+ streamChat.isVideoAttachment(attachment) && !hasUploadError && uploadState !== "uploading" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__attachment-preview-media__video-indicator", children: [
16619
+ /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconVideoSolid, {}),
16620
+ attachment.duration && /* @__PURE__ */ jsxRuntime.jsx("div", { children: attachment.duration })
16621
+ ] }),
16622
+ hasFatalError && /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconExclamationCircle, {}),
16623
+ hasRetriableError && /* @__PURE__ */ jsxRuntime.jsx(
16624
+ WithAudioPlayback.Button,
16625
+ {
16626
+ appearance: "solid",
16627
+ "aria-label": t("aria/Retry upload"),
16628
+ circular: true,
16629
+ className: "str-chat__attachment-preview-media__retry-upload-button",
16630
+ "data-testid": "video-preview-item-retry-button",
16631
+ onClick: retry,
16632
+ size: "sm",
16633
+ variant: "danger",
16634
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconArrowRotateClockwise, {})
16635
+ }
16636
+ )
16637
+ ] })
16638
+ ] }),
16639
+ /* @__PURE__ */ jsxRuntime.jsx(
16640
+ RemoveAttachmentPreviewButton,
16641
+ {
16642
+ "data-testid": "video-preview-item-delete-button",
16643
+ onClick: () => {
16644
+ if (id) removeAttachments([id]);
16645
+ },
16646
+ uploadState
16647
+ }
16648
+ )
16649
+ ]
16650
+ }
16651
+ );
16652
+ };
16653
+ const toGalleryItemDescriptors = (...args) => toBaseImageDescriptors(...args);
16654
+ const GalleryContext = React.createContext(void 0);
16655
+ const useGalleryContext = () => {
16656
+ const contextValue = React.useContext(GalleryContext);
16657
+ if (!contextValue) {
16658
+ console.warn(
16659
+ `The useGalleryContext hook was called outside of the GalleryContext provider. Make sure this hook is called within a child of the Gallery component.`
16660
+ );
16661
+ return {};
16662
+ }
16663
+ return contextValue;
16664
+ };
16665
+ const GalleryHeader = ({ currentItem }) => {
16666
+ const { t } = WithAudioPlayback.useTranslationContext();
16667
+ const { MessageTimestamp: MessageTimestamp$1 = MessageTimestamp } = WithAudioPlayback.useComponentContext();
16668
+ const { isMyMessage, message } = useMessageContext();
16669
+ const modalContext = React.useContext(ModalContext);
16670
+ const headerTitle = isMyMessage?.() && t("You") || message?.user?.name || message?.user?.id || currentItem.title || t("User uploaded content");
16671
+ const downloadUrl = React.useMemo(() => {
16672
+ const rawDownloadUrl = currentItem.videoUrl ?? currentItem.imageUrl;
16673
+ if (!rawDownloadUrl) return void 0;
16674
+ const sanitizedUrl = sanitizeUrl.sanitizeUrl(rawDownloadUrl);
16675
+ return sanitizedUrl === "about:blank" ? void 0 : sanitizedUrl;
16676
+ }, [currentItem.imageUrl, currentItem.videoUrl]);
16677
+ const downloadLabel = t("aria/Download attachment");
16678
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__header", children: [
16679
+ /* @__PURE__ */ jsxRuntime.jsx("div", { "aria-hidden": "true", className: "str-chat__gallery__header-spacer" }),
16680
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__header-meta", children: [
16681
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__gallery__title", children: headerTitle }),
16682
+ message?.created_at ? /* @__PURE__ */ jsxRuntime.jsx(MessageTimestamp$1, { customClass: "str-chat__gallery__timestamp" }) : null
16683
+ ] }),
16684
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__header-actions", children: [
16685
+ downloadUrl ? /* @__PURE__ */ jsxRuntime.jsx(
16686
+ "a",
16687
+ {
16688
+ "aria-label": downloadLabel,
16689
+ className: "str-chat__gallery__action-button str-chat__gallery__action-button--download",
16690
+ download: true,
16691
+ href: downloadUrl,
16692
+ rel: "noreferrer",
16693
+ target: "_blank",
16694
+ title: downloadLabel,
16695
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconArrowDownCircle, {})
16696
+ }
16697
+ ) : null,
16698
+ modalContext?.close ? /* @__PURE__ */ jsxRuntime.jsx(
16699
+ WithAudioPlayback.Button,
16700
+ {
16701
+ "aria-label": t("Close"),
16702
+ className: "str-chat__gallery__action-button str-chat__gallery__action-button--close",
16703
+ onClick: modalContext.close,
16704
+ title: t("Close"),
16705
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconCrossMedium, {})
16706
+ }
16707
+ ) : null
16708
+ ] })
16709
+ ] });
16710
+ };
16711
+ const VideoPlayer = ({ isPlaying, thumbnailUrl, videoUrl }) => {
16712
+ const { VideoPlayer: VideoPlayerContext } = WithAudioPlayback.useComponentContext();
16713
+ return VideoPlayerContext ? /* @__PURE__ */ jsxRuntime.jsx(VideoPlayerContext, { thumbnailUrl, videoUrl }) : /* @__PURE__ */ jsxRuntime.jsx(
16714
+ ReactPlayer,
16715
+ {
16716
+ className: "react-player",
16717
+ config: { file: { attributes: { poster: thumbnailUrl } } },
16718
+ controls: true,
16719
+ height: "100%",
16720
+ playing: isPlaying,
16721
+ url: videoUrl,
16722
+ width: "100%"
16723
+ }
16724
+ );
16725
+ };
16726
+ const VideoThumbnail = ({
16727
+ className,
16728
+ onPlay,
16729
+ ...imageProps
16730
+ }) => {
16731
+ const { t } = WithAudioPlayback.useTranslationContext();
16732
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-attachment__video-thumbnail", children: [
16733
+ /* @__PURE__ */ jsxRuntime.jsx(
16734
+ BaseImage,
16735
+ {
16736
+ className: clsx("str-chat__message-attachment__video-thumbnail-image", className),
16737
+ ...imageProps
16738
+ }
16739
+ ),
16740
+ onPlay ? /* @__PURE__ */ jsxRuntime.jsx(
16741
+ WithAudioPlayback.Button,
16742
+ {
16743
+ appearance: "solid",
16744
+ "aria-label": t("Play video"),
16745
+ circular: true,
16746
+ className: clsx(
16747
+ "str-chat__message-attachment__video-thumbnail__play-indicator"
16748
+ ),
16749
+ onClick: onPlay,
16750
+ size: "lg",
16751
+ variant: "secondary",
16752
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconPlaySolid, {})
16753
+ }
16754
+ ) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-attachment__video-thumbnail__play-indicator", children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconPlaySolid, {}) })
16755
+ ] });
16756
+ };
16757
+ const SWIPE_THRESHOLD = 50;
16758
+ const TRANSITION_DURATION = 300;
16759
+ const GalleryUI = () => {
16760
+ const { t } = WithAudioPlayback.useTranslationContext();
16761
+ const {
16762
+ closeOnBackgroundClick,
16763
+ currentIndex,
16764
+ currentItem,
16765
+ goToNext,
16766
+ goToPrevious,
16767
+ hasNext,
16768
+ hasPrevious,
16769
+ itemCount,
16770
+ onRequestClose
16771
+ } = useGalleryContext();
16772
+ const modalContext = React.useContext(ModalContext);
16773
+ const [showVideo, setShowVideo] = React.useState(false);
16774
+ const isTransitioningRef = React.useRef(false);
16775
+ const [slideOffset, setSlideOffset] = React.useState(0);
16776
+ const [isDragging, setIsDragging] = React.useState(false);
16777
+ const [slideDirection, setSlideDirection] = React.useState(
16778
+ null
16779
+ );
16780
+ const ignoreNextClickRef = React.useRef(false);
16781
+ const touchStartRef = React.useRef(null);
16782
+ const isVerticalSwipeRef = React.useRef(false);
16783
+ const containerRef = React.useRef(null);
16784
+ React.useEffect(() => {
16785
+ setShowVideo(false);
16786
+ }, [currentIndex]);
16787
+ const prevIndexRef = React.useRef(currentIndex);
16788
+ React.useEffect(() => {
16789
+ if (prevIndexRef.current === currentIndex) return;
16790
+ const direction = currentIndex > prevIndexRef.current ? "forward" : "backward";
16791
+ setSlideDirection(direction);
16792
+ setSlideOffset(0);
16793
+ setIsDragging(false);
16794
+ isTransitioningRef.current = true;
16795
+ const timer = setTimeout(() => {
16796
+ setSlideDirection(null);
16797
+ isTransitioningRef.current = false;
16798
+ }, TRANSITION_DURATION);
16799
+ prevIndexRef.current = currentIndex;
16800
+ return () => clearTimeout(timer);
16801
+ }, [currentIndex]);
16802
+ const handleGoToNext = React.useCallback(() => {
16803
+ if (isTransitioningRef.current) return;
16804
+ goToNext();
16805
+ }, [goToNext]);
16806
+ const handleGoToPrevious = React.useCallback(() => {
16807
+ if (isTransitioningRef.current) return;
16808
+ goToPrevious();
16809
+ }, [goToPrevious]);
16810
+ const handleKeyDown = React.useCallback(
16811
+ (event) => {
16812
+ if (event.key === "ArrowLeft") {
16813
+ event.preventDefault();
16814
+ handleGoToPrevious();
16815
+ } else if (event.key === "ArrowRight") {
16816
+ event.preventDefault();
16817
+ handleGoToNext();
16818
+ }
16819
+ },
16820
+ [handleGoToNext, handleGoToPrevious]
16821
+ );
16822
+ React.useEffect(() => {
16823
+ document.addEventListener("keydown", handleKeyDown);
16824
+ return () => document.removeEventListener("keydown", handleKeyDown);
16825
+ }, [handleKeyDown]);
16826
+ const handleTouchStart = React.useCallback((event) => {
16827
+ if (isTransitioningRef.current) return;
16828
+ const touch = event.touches[0];
16829
+ ignoreNextClickRef.current = false;
16830
+ touchStartRef.current = { x: touch.clientX, y: touch.clientY };
16831
+ isVerticalSwipeRef.current = false;
16832
+ }, []);
16833
+ const handleTouchMove = React.useCallback(
16834
+ (event) => {
16835
+ if (!touchStartRef.current || isTransitioningRef.current) return;
16836
+ const touch = event.touches[0];
16837
+ const deltaX = touch.clientX - touchStartRef.current.x;
16838
+ const deltaY = touch.clientY - touchStartRef.current.y;
16839
+ if (!isDragging && !isVerticalSwipeRef.current) {
16840
+ if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > 10) {
16841
+ ignoreNextClickRef.current = true;
16842
+ isVerticalSwipeRef.current = true;
16843
+ return;
16844
+ }
16845
+ if (Math.abs(deltaX) > 10) {
16846
+ ignoreNextClickRef.current = true;
16847
+ setIsDragging(true);
16848
+ }
16849
+ }
16850
+ if (isVerticalSwipeRef.current) return;
16851
+ if (!hasNext && deltaX < 0 || !hasPrevious && deltaX > 0) {
16852
+ setSlideOffset(deltaX * 0.3);
16853
+ } else {
16854
+ setSlideOffset(deltaX);
16855
+ }
16856
+ },
16857
+ [isDragging, hasNext, hasPrevious]
16858
+ );
16859
+ const handleTouchEnd = React.useCallback(() => {
16860
+ if (!touchStartRef.current || isVerticalSwipeRef.current) {
16861
+ if (isVerticalSwipeRef.current) ignoreNextClickRef.current = true;
16862
+ touchStartRef.current = null;
16863
+ return;
16864
+ }
16865
+ const offset = slideOffset;
16866
+ if (isDragging || Math.abs(offset) > 10) {
16867
+ ignoreNextClickRef.current = true;
16868
+ }
16869
+ touchStartRef.current = null;
16870
+ if (Math.abs(offset) >= SWIPE_THRESHOLD) {
16871
+ if (offset < 0 && hasNext) {
16872
+ goToNext();
16873
+ } else if (offset > 0 && hasPrevious) {
16874
+ goToPrevious();
16875
+ } else {
16876
+ setSlideOffset(0);
16877
+ }
16878
+ } else {
16879
+ setSlideOffset(0);
16880
+ }
16881
+ setIsDragging(false);
16882
+ }, [slideOffset, hasNext, hasPrevious, goToNext, goToPrevious, isDragging]);
16883
+ const requestClose = modalContext?.close ?? onRequestClose;
16884
+ const handleBackgroundClick = React.useCallback(
16885
+ (event) => {
16886
+ if (event.target !== event.currentTarget) return;
16887
+ if (ignoreNextClickRef.current) {
16888
+ ignoreNextClickRef.current = false;
16889
+ return;
16890
+ }
16891
+ if (!closeOnBackgroundClick) return;
16892
+ requestClose?.();
16893
+ },
16894
+ [closeOnBackgroundClick, requestClose]
16895
+ );
16896
+ const mediaStyle = isDragging || slideOffset !== 0 && slideDirection === null ? { transform: `translateX(${slideOffset}px)` } : {};
16897
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery", children: [
16898
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__main", children: [
16899
+ /* @__PURE__ */ jsxRuntime.jsx(GalleryHeader, { currentItem }),
16900
+ /* @__PURE__ */ jsxRuntime.jsx(
16901
+ NavButton,
16902
+ {
16903
+ "aria-label": t("Previous image"),
16904
+ className: clsx(
16905
+ "str-chat__gallery__nav-button--prev",
16906
+ !hasPrevious && "str-chat__gallery__nav-button--hidden"
16907
+ ),
16908
+ disabled: !hasPrevious,
16909
+ onClick: handleGoToPrevious,
16910
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconChevronLeft, {})
16911
+ }
16912
+ ),
16913
+ /* @__PURE__ */ jsxRuntime.jsx(
16914
+ "div",
16915
+ {
16916
+ className: "str-chat__gallery__slide-container",
16917
+ onClick: handleBackgroundClick,
16918
+ onTouchEnd: handleTouchEnd,
16919
+ onTouchMove: handleTouchMove,
16920
+ onTouchStart: handleTouchStart,
16921
+ ref: containerRef,
16922
+ children: /* @__PURE__ */ jsxRuntime.jsx(
16923
+ "div",
17095
16924
  {
17096
- alt: thumbnail.alt,
17097
- className: "str-chat__attachment-preview-media__thumbnail",
17098
- onError: handleThumbnailLoadError,
17099
- src: thumbnail.url,
17100
- title: thumbnail.title
16925
+ className: clsx({
16926
+ "str-chat__gallery__media--dragging": isDragging,
16927
+ "str-chat__gallery__media--slide-backward": !isDragging && slideDirection === "backward",
16928
+ "str-chat__gallery__media--slide-forward": !isDragging && slideDirection === "forward"
16929
+ }),
16930
+ style: mediaStyle,
16931
+ children: currentItem.videoUrl && currentItem.videoThumbnailUrl ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__gallery__media str-chat__gallery__media--video", children: showVideo ? /* @__PURE__ */ jsxRuntime.jsx(VideoPlayer, { isPlaying: true, videoUrl: currentItem.videoUrl }) : /* @__PURE__ */ jsxRuntime.jsx(
16932
+ VideoThumbnail,
16933
+ {
16934
+ alt: currentItem.title ?? "",
16935
+ onPlay: () => setShowVideo(true),
16936
+ src: currentItem.videoThumbnailUrl
16937
+ }
16938
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__gallery__media str-chat__gallery__media--image", children: /* @__PURE__ */ jsxRuntime.jsx(BaseImage, { alt: currentItem.alt, src: currentItem.imageUrl }) })
17101
16939
  }
16940
+ )
16941
+ }
16942
+ ),
16943
+ /* @__PURE__ */ jsxRuntime.jsx(
16944
+ NavButton,
16945
+ {
16946
+ "aria-label": t("Next image"),
16947
+ className: clsx(
16948
+ "str-chat__gallery__nav-button--next",
16949
+ !hasNext && "str-chat__gallery__nav-button--hidden"
17102
16950
  ),
17103
- /* @__PURE__ */ jsxRuntime.jsxs("div", { className: clsx("str-chat__attachment-preview-media__overlay"), children: [
17104
- isUploading && /* @__PURE__ */ jsxRuntime.jsx(LoadingIndicator2, {}),
17105
- streamChat.isVideoAttachment(attachment) && !hasUploadError && uploadState !== "uploading" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__attachment-preview-media__video-indicator", children: [
17106
- /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconVideoSolid, {}),
17107
- attachment.duration && /* @__PURE__ */ jsxRuntime.jsx("div", { children: attachment.duration })
17108
- ] }),
17109
- hasFatalError && /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconExclamationCircle, {}),
17110
- hasRetriableError && /* @__PURE__ */ jsxRuntime.jsx(
17111
- WithAudioPlayback.Button,
17112
- {
17113
- appearance: "solid",
17114
- "aria-label": t("aria/Retry upload"),
17115
- circular: true,
17116
- className: "str-chat__attachment-preview-media__retry-upload-button",
17117
- "data-testid": "video-preview-item-retry-button",
17118
- onClick: retry,
17119
- size: "sm",
17120
- variant: "danger",
17121
- children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconArrowRotateClockwise, {})
17122
- }
17123
- )
17124
- ] })
17125
- ] }),
17126
- /* @__PURE__ */ jsxRuntime.jsx(
17127
- RemoveAttachmentPreviewButton,
17128
- {
17129
- "data-testid": "video-preview-item-delete-button",
17130
- onClick: () => {
17131
- if (id) removeAttachments([id]);
17132
- },
17133
- uploadState
17134
- }
17135
- )
17136
- ]
17137
- }
16951
+ disabled: !hasNext,
16952
+ onClick: handleGoToNext,
16953
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconChevronRight, {})
16954
+ }
16955
+ )
16956
+ ] }),
16957
+ itemCount > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__gallery__position-indicator", children: [
16958
+ currentIndex + 1,
16959
+ " of ",
16960
+ itemCount
16961
+ ] })
16962
+ ] });
16963
+ };
16964
+ const NavButton = ({ className, ...props }) => /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.Button, { ...props, className: clsx("str-chat__gallery__nav-button", className) });
16965
+ const Gallery = ({
16966
+ closeOnBackgroundClick = true,
16967
+ GalleryUI: GalleryUI$1,
16968
+ initialIndex = 0,
16969
+ items,
16970
+ onIndexChange,
16971
+ onRequestClose
16972
+ }) => {
16973
+ const { GalleryUI: ContextGalleryUI } = WithAudioPlayback.useComponentContext();
16974
+ const ResolvedGalleryUI = GalleryUI$1 ?? ContextGalleryUI ?? GalleryUI;
16975
+ const [currentIndex, setCurrentIndex] = React.useState(initialIndex);
16976
+ const itemCount = items.length;
16977
+ const goToIndex = React.useCallback(
16978
+ (index) => {
16979
+ if (index >= 0 && index < itemCount) {
16980
+ setCurrentIndex(index);
16981
+ }
16982
+ },
16983
+ [itemCount]
16984
+ );
16985
+ const goToNext = React.useCallback(() => {
16986
+ setCurrentIndex((prev) => prev < itemCount - 1 ? prev + 1 : prev);
16987
+ }, [itemCount]);
16988
+ const goToPrevious = React.useCallback(() => {
16989
+ setCurrentIndex((prev) => prev > 0 ? prev - 1 : prev);
16990
+ }, []);
16991
+ React.useEffect(() => {
16992
+ onIndexChange?.(currentIndex);
16993
+ }, [currentIndex, onIndexChange]);
16994
+ const hasNext = currentIndex < itemCount - 1;
16995
+ const hasPrevious = currentIndex > 0;
16996
+ const currentItem = items[currentIndex];
16997
+ const contextValue = React.useMemo(
16998
+ () => ({
16999
+ closeOnBackgroundClick,
17000
+ currentIndex,
17001
+ currentItem,
17002
+ goToIndex,
17003
+ goToNext,
17004
+ goToPrevious,
17005
+ hasNext,
17006
+ hasPrevious,
17007
+ itemCount,
17008
+ items,
17009
+ onRequestClose
17010
+ }),
17011
+ [
17012
+ closeOnBackgroundClick,
17013
+ currentIndex,
17014
+ currentItem,
17015
+ goToIndex,
17016
+ goToNext,
17017
+ goToPrevious,
17018
+ hasNext,
17019
+ hasPrevious,
17020
+ itemCount,
17021
+ items,
17022
+ onRequestClose
17023
+ ]
17138
17024
  );
17025
+ return /* @__PURE__ */ jsxRuntime.jsx(GalleryContext.Provider, { value: contextValue, children: /* @__PURE__ */ jsxRuntime.jsx(ResolvedGalleryUI, {}) });
17139
17026
  };
17140
17027
  const AttachmentPreviewList = ({
17141
17028
  AudioAttachmentPreview: AudioAttachmentPreview2 = FileAttachmentPreview,
@@ -17145,73 +17032,107 @@ const AttachmentPreviewList = ({
17145
17032
  VideoAttachmentPreview = MediaAttachmentPreview
17146
17033
  }) => {
17147
17034
  const messageComposer = WithAudioPlayback.useMessageComposerController();
17035
+ const { Modal = GlobalModal } = WithAudioPlayback.useComponentContext();
17036
+ const [showPreview, setShowPreview] = React.useState(false);
17037
+ const initialIndexRef = React.useRef(0);
17148
17038
  const { attachments } = useAttachmentsForPreview();
17149
17039
  const filteredAttachments = React.useMemo(
17150
17040
  () => attachments.filter((a) => !streamChat.isVoiceRecordingAttachment(a)),
17151
17041
  [attachments]
17152
17042
  );
17043
+ const { galleryItems, previewIndexById } = React.useMemo(() => {
17044
+ const items = [];
17045
+ const indexById = {};
17046
+ for (const a of attachments) {
17047
+ if (streamChat.isLocalImageAttachment(a) || streamChat.isLocalVideoAttachment(a)) {
17048
+ const descriptor = toBaseImageDescriptors(a);
17049
+ if (descriptor) {
17050
+ indexById[a.localMetadata.id] = items.length;
17051
+ items.push(descriptor);
17052
+ }
17053
+ }
17054
+ }
17055
+ return { galleryItems: items, previewIndexById: indexById };
17056
+ }, [attachments]);
17057
+ const openPreviewAtIndex = React.useCallback((index) => {
17058
+ initialIndexRef.current = index;
17059
+ setShowPreview(true);
17060
+ }, []);
17153
17061
  if (!filteredAttachments.length) return null;
17154
- return /* @__PURE__ */ jsxRuntime.jsx(
17062
+ return /* @__PURE__ */ jsxRuntime.jsxs(
17155
17063
  "div",
17156
17064
  {
17157
17065
  className: "str-chat__attachment-preview-list",
17158
17066
  "data-testid": "attachment-preview-list",
17159
- children: attachments.map((attachment) => {
17160
- if (streamChat.isScrapedContent(attachment)) return null;
17161
- if (streamChat.isLocalVoiceRecordingAttachment(attachment)) return null;
17162
- if (streamChat.isLocalAudioAttachment(attachment)) {
17163
- return /* @__PURE__ */ jsxRuntime.jsx(
17164
- AudioAttachmentPreview2,
17165
- {
17166
- attachment,
17167
- handleRetry: messageComposer.attachmentManager.uploadAttachment,
17168
- removeAttachments: messageComposer.attachmentManager.removeAttachments
17169
- },
17170
- attachment.localMetadata.id || attachment.asset_url
17171
- );
17172
- } else if (streamChat.isLocalVideoAttachment(attachment)) {
17173
- return /* @__PURE__ */ jsxRuntime.jsx(
17174
- VideoAttachmentPreview,
17175
- {
17176
- attachment,
17177
- handleRetry: messageComposer.attachmentManager.uploadAttachment,
17178
- removeAttachments: messageComposer.attachmentManager.removeAttachments
17179
- },
17180
- attachment.localMetadata.id || attachment.asset_url
17181
- );
17182
- } else if (streamChat.isLocalImageAttachment(attachment)) {
17183
- return /* @__PURE__ */ jsxRuntime.jsx(
17184
- ImageAttachmentPreview,
17185
- {
17186
- attachment,
17187
- handleRetry: messageComposer.attachmentManager.uploadAttachment,
17188
- removeAttachments: messageComposer.attachmentManager.removeAttachments
17189
- },
17190
- attachment.localMetadata.id || attachment.image_url
17191
- );
17192
- } else if (streamChat.isLocalFileAttachment(attachment)) {
17193
- return /* @__PURE__ */ jsxRuntime.jsx(
17194
- FileAttachmentPreview$1,
17195
- {
17196
- attachment,
17197
- handleRetry: messageComposer.attachmentManager.uploadAttachment,
17198
- removeAttachments: messageComposer.attachmentManager.removeAttachments
17199
- },
17200
- attachment.localMetadata.id || attachment.asset_url
17201
- );
17202
- } else if (streamChat.isLocalAttachment(attachment)) {
17203
- return /* @__PURE__ */ jsxRuntime.jsx(
17204
- UnsupportedAttachmentPreview$1,
17205
- {
17206
- attachment,
17207
- handleRetry: messageComposer.attachmentManager.uploadAttachment,
17208
- removeAttachments: messageComposer.attachmentManager.removeAttachments
17209
- },
17210
- attachment.localMetadata.id
17211
- );
17212
- }
17213
- return null;
17214
- })
17067
+ children: [
17068
+ attachments.map((attachment) => {
17069
+ if (streamChat.isScrapedContent(attachment)) return null;
17070
+ if (streamChat.isLocalVoiceRecordingAttachment(attachment)) return null;
17071
+ if (streamChat.isLocalAudioAttachment(attachment)) {
17072
+ return /* @__PURE__ */ jsxRuntime.jsx(
17073
+ AudioAttachmentPreview2,
17074
+ {
17075
+ attachment,
17076
+ handleRetry: messageComposer.attachmentManager.uploadAttachment,
17077
+ removeAttachments: messageComposer.attachmentManager.removeAttachments
17078
+ },
17079
+ attachment.localMetadata.id || attachment.asset_url
17080
+ );
17081
+ } else if (streamChat.isLocalVideoAttachment(attachment)) {
17082
+ return /* @__PURE__ */ jsxRuntime.jsx(
17083
+ VideoAttachmentPreview,
17084
+ {
17085
+ attachment,
17086
+ handleRetry: messageComposer.attachmentManager.uploadAttachment,
17087
+ openPreview: () => openPreviewAtIndex(previewIndexById[attachment.localMetadata.id] ?? 0),
17088
+ removeAttachments: messageComposer.attachmentManager.removeAttachments
17089
+ },
17090
+ attachment.localMetadata.id || attachment.asset_url
17091
+ );
17092
+ } else if (streamChat.isLocalImageAttachment(attachment)) {
17093
+ return /* @__PURE__ */ jsxRuntime.jsx(
17094
+ ImageAttachmentPreview,
17095
+ {
17096
+ attachment,
17097
+ handleRetry: messageComposer.attachmentManager.uploadAttachment,
17098
+ openPreview: () => openPreviewAtIndex(previewIndexById[attachment.localMetadata.id] ?? 0),
17099
+ removeAttachments: messageComposer.attachmentManager.removeAttachments
17100
+ },
17101
+ attachment.localMetadata.id || attachment.image_url
17102
+ );
17103
+ } else if (streamChat.isLocalFileAttachment(attachment)) {
17104
+ return /* @__PURE__ */ jsxRuntime.jsx(
17105
+ FileAttachmentPreview$1,
17106
+ {
17107
+ attachment,
17108
+ handleRetry: messageComposer.attachmentManager.uploadAttachment,
17109
+ removeAttachments: messageComposer.attachmentManager.removeAttachments
17110
+ },
17111
+ attachment.localMetadata.id || attachment.asset_url
17112
+ );
17113
+ } else if (streamChat.isLocalAttachment(attachment)) {
17114
+ return /* @__PURE__ */ jsxRuntime.jsx(
17115
+ UnsupportedAttachmentPreview$1,
17116
+ {
17117
+ attachment,
17118
+ handleRetry: messageComposer.attachmentManager.uploadAttachment,
17119
+ removeAttachments: messageComposer.attachmentManager.removeAttachments
17120
+ },
17121
+ attachment.localMetadata.id
17122
+ );
17123
+ }
17124
+ return null;
17125
+ }),
17126
+ galleryItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(
17127
+ Modal,
17128
+ {
17129
+ className: "str-chat__gallery-modal",
17130
+ onClose: () => setShowPreview(false),
17131
+ open: showPreview,
17132
+ children: /* @__PURE__ */ jsxRuntime.jsx(Gallery, { initialIndex: initialIndexRef.current, items: galleryItems })
17133
+ }
17134
+ )
17135
+ ]
17215
17136
  }
17216
17137
  );
17217
17138
  };
@@ -17239,11 +17160,9 @@ const VoiceRecordingPreviewSlot = ({
17239
17160
  }
17240
17161
  );
17241
17162
  };
17242
- const textComposerStateSelector$4 = ({ command }) => ({ command });
17243
- const CommandChip = () => {
17163
+ const CommandChip = ({ command }) => {
17244
17164
  const { textComposer } = WithAudioPlayback.useMessageComposerController();
17245
17165
  const { textareaRef } = WithAudioPlayback.useMessageComposerContext();
17246
- const { command } = WithAudioPlayback.useStateStore(textComposer.state, textComposerStateSelector$4);
17247
17166
  if (!command) return null;
17248
17167
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__command-chip", children: [
17249
17168
  /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconThunder, {}),
@@ -17542,9 +17461,12 @@ const ToggleRecordingButton = () => {
17542
17461
  );
17543
17462
  };
17544
17463
  const AudioRecorderRecordingControls = () => {
17464
+ const { client } = WithAudioPlayback.useChatContext();
17465
+ const { t } = WithAudioPlayback.useTranslationContext();
17545
17466
  const {
17546
17467
  recordingController: { completeRecording, recorder, recording, recordingState }
17547
17468
  } = WithAudioPlayback.useMessageComposerContext();
17469
+ const panel = WithAudioPlayback.useNotificationTarget();
17548
17470
  const isUploadingFile = recording?.localMetadata?.uploadState === "uploading";
17549
17471
  if (!recorder) return null;
17550
17472
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__audio_recorder__recording-controls", children: [
@@ -17556,7 +17478,17 @@ const AudioRecorderRecordingControls = () => {
17556
17478
  className: "str-chat__audio_recorder__cancel-button",
17557
17479
  "data-testid": "cancel-recording-audio-button",
17558
17480
  disabled: isUploadingFile,
17559
- onClick: recorder.cancel,
17481
+ onClick: () => {
17482
+ recorder.cancel();
17483
+ client.notifications.addInfo({
17484
+ message: t("Voice message deleted"),
17485
+ options: {
17486
+ tags: WithAudioPlayback.addNotificationTargetTag(panel),
17487
+ type: "audioRecording:cancel:success"
17488
+ },
17489
+ origin: { emitter: "AudioRecorder" }
17490
+ });
17491
+ },
17560
17492
  size: "sm",
17561
17493
  variant: "secondary",
17562
17494
  children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconTrashBin, {})
@@ -18080,6 +18012,12 @@ const TextareaComposer = ({
18080
18012
  textComposer.state,
18081
18013
  textComposerStateSelector$1
18082
18014
  );
18015
+ const autosizeRows = !text2 && minRows == null ? 1 : void 0;
18016
+ const textareaStyle = text2 ? void 0 : {
18017
+ overflow: "hidden",
18018
+ textOverflow: "ellipsis",
18019
+ whiteSpace: "nowrap"
18020
+ };
18083
18021
  const { enabled } = WithAudioPlayback.useStateStore(messageComposer.configState, configStateSelector);
18084
18022
  const { quotedMessage } = WithAudioPlayback.useStateStore(
18085
18023
  messageComposer.state,
@@ -18201,6 +18139,12 @@ const TextareaComposer = ({
18201
18139
  if (!textareaRef.current || textareaIsFocused || !focus2) return;
18202
18140
  textareaRef.current.focus();
18203
18141
  }, [attachments, focus2, quotedMessage, textareaRef]);
18142
+ React.useEffect(
18143
+ () => () => {
18144
+ messageComposer.clear();
18145
+ },
18146
+ [messageComposer]
18147
+ );
18204
18148
  React.useLayoutEffect(() => {
18205
18149
  const textarea = textareaRef.current;
18206
18150
  if (!textarea || isComposing) return;
@@ -18233,8 +18177,8 @@ const TextareaComposer = ({
18233
18177
  ),
18234
18178
  "data-testid": "message-input",
18235
18179
  disabled: !enabled || !!cooldownRemaining,
18236
- maxRows,
18237
- minRows,
18180
+ maxRows: autosizeRows ?? maxRows,
18181
+ minRows: autosizeRows ?? minRows,
18238
18182
  onBlur,
18239
18183
  onChange: changeHandler,
18240
18184
  onCompositionEnd,
@@ -18246,7 +18190,8 @@ const TextareaComposer = ({
18246
18190
  placeholder,
18247
18191
  ref: (ref) => {
18248
18192
  textareaRef.current = ref;
18249
- }
18193
+ },
18194
+ style: textareaStyle
18250
18195
  }
18251
18196
  ),
18252
18197
  !isComposing && /* @__PURE__ */ jsxRuntime.jsx(
@@ -18578,7 +18523,7 @@ const MessageComposerUI = () => {
18578
18523
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-composer-controls", children: [
18579
18524
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-composer-controls__text-composition-controls", children: [
18580
18525
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__message-composer-controls__text-composition-controls__text", children: [
18581
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-composer-controls__text-composition-controls__command-chip-container", children: /* @__PURE__ */ jsxRuntime.jsx(CommandChip$1, {}) }),
18526
+ command && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-composer-controls__text-composition-controls__command-chip-container", children: /* @__PURE__ */ jsxRuntime.jsx(CommandChip$1, { command }) }),
18582
18527
  /* @__PURE__ */ jsxRuntime.jsx(TextareaComposer$1, {})
18583
18528
  ] }),
18584
18529
  /* @__PURE__ */ jsxRuntime.jsx(SendToChannelCheckbox$1, {})
@@ -18971,7 +18916,7 @@ const useChat = ({
18971
18916
  };
18972
18917
  React.useEffect(() => {
18973
18918
  if (!client) return;
18974
- const version = "14.0.0-beta.1";
18919
+ const version = "14.0.0-beta.2";
18975
18920
  const userAgent = client.getUserAgent();
18976
18921
  if (!userAgent.includes("stream-chat-react")) {
18977
18922
  client.setUserAgent(`stream-chat-react-${version}-${userAgent}`);
@@ -19478,7 +19423,7 @@ ReactionSelector.getDialogId = (({ messageId, threadList }) => {
19478
19423
  });
19479
19424
  ReactionSelector.displayName = "ReactionSelector";
19480
19425
  const ReactionSelectorWithButton = ({
19481
- ReactionIcon: ReactionIcon2
19426
+ ReactionIcon
19482
19427
  }) => {
19483
19428
  const { t } = WithAudioPlayback.useTranslationContext("ReactionSelectorWithButton");
19484
19429
  const { isMyMessage, message, threadList } = useMessageContext();
@@ -19512,7 +19457,7 @@ const ReactionSelectorWithButton = ({
19512
19457
  "data-testid": "message-reaction-action",
19513
19458
  onClick: () => dialog?.toggle(),
19514
19459
  ref: buttonRef,
19515
- children: /* @__PURE__ */ jsxRuntime.jsx(ReactionIcon2, { className: "str-chat__message-action-icon" })
19460
+ children: /* @__PURE__ */ jsxRuntime.jsx(ReactionIcon, { className: "str-chat__message-action-icon" })
19516
19461
  }
19517
19462
  )
19518
19463
  ] });
@@ -19849,8 +19794,7 @@ const DefaultMessageActionComponents = {
19849
19794
  const { closeMenu } = useContextMenuContext();
19850
19795
  const { client } = WithAudioPlayback.useChatContext();
19851
19796
  const { Modal = GlobalModal } = WithAudioPlayback.useComponentContext();
19852
- const { removeMessage } = WithAudioPlayback.useChannelActionContext();
19853
- const { handleDelete, message } = useMessageContext();
19797
+ const { handleDelete } = useMessageContext();
19854
19798
  const panel = WithAudioPlayback.useNotificationTarget();
19855
19799
  const { t } = WithAudioPlayback.useTranslationContext();
19856
19800
  const [openModal, setOpenModal] = React.useState(false);
@@ -19876,29 +19820,20 @@ const DefaultMessageActionComponents = {
19876
19820
  closeMenu();
19877
19821
  },
19878
19822
  onDelete: async () => {
19879
- if (message.type === "error") removeMessage(message);
19880
- else {
19881
- try {
19882
- await handleDelete();
19883
- client.notifications.addSuccess({
19884
- message: t("Message deleted"),
19885
- options: {
19886
- tags: WithAudioPlayback.addNotificationTargetTag(panel)
19887
- },
19888
- origin: { emitter: "MessageActions" }
19889
- });
19890
- } catch (error) {
19891
- client.notifications.addError({
19892
- message: t("Failed to delete the message"),
19893
- options: {
19894
- tags: WithAudioPlayback.addNotificationTargetTag(panel)
19895
- },
19896
- origin: { emitter: "MessageActions" }
19897
- });
19898
- }
19823
+ try {
19824
+ await handleDelete();
19825
+ client.notifications.addSuccess({
19826
+ message: t("Message deleted"),
19827
+ options: {
19828
+ tags: WithAudioPlayback.addNotificationTargetTag(panel)
19829
+ },
19830
+ origin: { emitter: "MessageActions" }
19831
+ });
19832
+ } catch {
19833
+ } finally {
19834
+ setOpenModal(false);
19835
+ closeMenu();
19899
19836
  }
19900
- setOpenModal(false);
19901
- closeMenu();
19902
19837
  }
19903
19838
  }
19904
19839
  ) })
@@ -19931,7 +19866,7 @@ const DefaultMessageActionComponents = {
19931
19866
  },
19932
19867
  quick: {
19933
19868
  React() {
19934
- return /* @__PURE__ */ jsxRuntime.jsx(ReactionSelectorWithButton, { ReactionIcon });
19869
+ return /* @__PURE__ */ jsxRuntime.jsx(ReactionSelectorWithButton, { ReactionIcon: WithAudioPlayback.IconEmojiSmile });
19935
19870
  },
19936
19871
  Reply() {
19937
19872
  const { handleOpenThread } = useMessageContext();
@@ -19943,7 +19878,7 @@ const DefaultMessageActionComponents = {
19943
19878
  className: "str-chat__message-reply-in-thread-button",
19944
19879
  "data-testid": "thread-action",
19945
19880
  onClick: handleOpenThread,
19946
- children: /* @__PURE__ */ jsxRuntime.jsx(ThreadIcon, { className: "str-chat__message-action-icon" })
19881
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconArrowShareLeft, { className: "str-chat__message-action-icon" })
19947
19882
  }
19948
19883
  );
19949
19884
  }
@@ -20615,7 +20550,7 @@ const MessageActions = ({
20615
20550
  },
20616
20551
  ref: setActionsBoxButtonElement,
20617
20552
  variant: "secondary",
20618
- children: /* @__PURE__ */ jsxRuntime.jsx(ActionsIcon, { className: "str-chat__message-action-icon" })
20553
+ children: /* @__PURE__ */ jsxRuntime.jsx(WithAudioPlayback.IconDotGrid1x3Horizontal, { className: "str-chat__message-action-icon" })
20619
20554
  }
20620
20555
  ),
20621
20556
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -20804,7 +20739,7 @@ const MessageUIWithContext = ({
20804
20739
  isAIGenerated ? /* @__PURE__ */ jsxRuntime.jsx(StreamedMessageText$1, { message, renderText: renderText2 }) : /* @__PURE__ */ jsxRuntime.jsx(MessageText, { message, renderText: renderText2 })
20805
20740
  ] }),
20806
20741
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-reactions-host", children: hasReactions && /* @__PURE__ */ jsxRuntime.jsx(MessageReactions$1, { reverse: true }) }),
20807
- /* @__PURE__ */ jsxRuntime.jsx(MessageErrorIcon, {})
20742
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__message-error-indicator", children: /* @__PURE__ */ jsxRuntime.jsx(ErrorBadge, {}) })
20808
20743
  ] })
20809
20744
  ]
20810
20745
  }
@@ -22488,7 +22423,7 @@ function defaultRenderMessages({
22488
22423
  return renderedMessages;
22489
22424
  }
22490
22425
  const findReverse = (items, matches) => {
22491
- for (let i = items.length - 1; i > 0; i -= 1) {
22426
+ for (let i = items.length - 1; i >= 0; i -= 1) {
22492
22427
  if (matches(items[i])) {
22493
22428
  return items[i];
22494
22429
  }
@@ -24354,7 +24289,7 @@ const SearchBar = () => {
24354
24289
  };
24355
24290
  const ChannelSearchResultItem = ({ item }) => {
24356
24291
  const { setActiveChannel } = WithAudioPlayback.useChatContext();
24357
- const { setChannels } = useChannelListContext();
24292
+ const { setChannels } = WithAudioPlayback.useChannelListContext();
24358
24293
  const onSelect = React.useCallback(() => {
24359
24294
  setActiveChannel(item);
24360
24295
  setChannels?.((channels) => uniqBy([item, ...channels], "cid"));
@@ -24377,7 +24312,7 @@ const MessageSearchResultItem = ({
24377
24312
  searchController,
24378
24313
  setActiveChannel
24379
24314
  } = WithAudioPlayback.useChatContext();
24380
- const { setChannels } = useChannelListContext();
24315
+ const { setChannels } = WithAudioPlayback.useChannelListContext();
24381
24316
  const channel = React.useMemo(() => {
24382
24317
  const { channel: channelData } = item;
24383
24318
  const type = channelData?.type ?? "unknown";
@@ -24410,7 +24345,7 @@ const MessageSearchResultItem = ({
24410
24345
  };
24411
24346
  const UserSearchResultItem = ({ item }) => {
24412
24347
  const { client, setActiveChannel } = WithAudioPlayback.useChatContext();
24413
- const { setChannels } = useChannelListContext();
24348
+ const { setChannels } = WithAudioPlayback.useChannelListContext();
24414
24349
  const { directMessagingChannelType } = useSearchContext();
24415
24350
  const onClick = React.useCallback(() => {
24416
24351
  const newChannel = client.channel(directMessagingChannelType, {
@@ -24936,7 +24871,7 @@ const UnMemoizedChannelList = (props) => {
24936
24871
  );
24937
24872
  const showChannelList = !searchIsActive;
24938
24873
  return /* @__PURE__ */ jsxRuntime.jsx(DialogManagerProvider, { id: `channel-list-dialog-manager-${stableId}`, children: /* @__PURE__ */ jsxRuntime.jsx(
24939
- ChannelListContextProvider,
24874
+ WithAudioPlayback.ChannelListContextProvider,
24940
24875
  {
24941
24876
  value: { channels, hasNextPage, loadNextPage, setChannels },
24942
24877
  children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className, ref: channelListRef, children: [
@@ -26622,7 +26557,8 @@ const ThreadList = ({ virtuosoProps }) => {
26622
26557
  };
26623
26558
  const IconsBySeverity = {
26624
26559
  error: WithAudioPlayback.IconExclamationCircle,
26625
- info: WithAudioPlayback.IconCircleInfoTooltip,
26560
+ info: null,
26561
+ // IconCircleInfoTooltip,
26626
26562
  loading: WithAudioPlayback.IconArrowRotateRightLeftRepeatRefresh,
26627
26563
  success: WithAudioPlayback.IconCheckmark2,
26628
26564
  warning: WithAudioPlayback.IconExclamationTriangle
@@ -26630,7 +26566,7 @@ const IconsBySeverity = {
26630
26566
  const DefaultNotificationIcon = ({ notification }) => {
26631
26567
  if (!notification.severity) return null;
26632
26568
  const Icon = IconsBySeverity[notification.severity] ?? null;
26633
- return Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, {});
26569
+ return Icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__notification-icon", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, {}) });
26634
26570
  };
26635
26571
  const Notification = React.forwardRef(
26636
26572
  ({
@@ -26674,7 +26610,7 @@ const Notification = React.forwardRef(
26674
26610
  ref,
26675
26611
  children: [
26676
26612
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__notification-content", children: [
26677
- Icon && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__notification-icon", children: /* @__PURE__ */ jsxRuntime.jsx(Icon, { notification }) }),
26613
+ Icon && /* @__PURE__ */ jsxRuntime.jsx(Icon, { notification }),
26678
26614
  /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__notification-message", children: displayMessage })
26679
26615
  ] }),
26680
26616
  notification.actions && notification.actions.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__notification-actions", children: notification.actions.map((action, index) => /* @__PURE__ */ jsxRuntime.jsx(
@@ -28034,6 +27970,8 @@ exports.Button = WithAudioPlayback.Button;
28034
27970
  exports.Channel = WithAudioPlayback.Channel;
28035
27971
  exports.ChannelActionContext = WithAudioPlayback.ChannelActionContext;
28036
27972
  exports.ChannelActionProvider = WithAudioPlayback.ChannelActionProvider;
27973
+ exports.ChannelListContext = WithAudioPlayback.ChannelListContext;
27974
+ exports.ChannelListContextProvider = WithAudioPlayback.ChannelListContextProvider;
28037
27975
  exports.ChannelStateContext = WithAudioPlayback.ChannelStateContext;
28038
27976
  exports.ChannelStateProvider = WithAudioPlayback.ChannelStateProvider;
28039
27977
  exports.ChatContext = WithAudioPlayback.ChatContext;
@@ -28119,6 +28057,7 @@ exports.IconEditBigSolid = WithAudioPlayback.IconEditBigSolid;
28119
28057
  exports.IconEmojiAddReaction = WithAudioPlayback.IconEmojiAddReaction;
28120
28058
  exports.IconEmojiSad = WithAudioPlayback.IconEmojiSad;
28121
28059
  exports.IconEmojiSmile = WithAudioPlayback.IconEmojiSmile;
28060
+ exports.IconExclamation = WithAudioPlayback.IconExclamation;
28122
28061
  exports.IconExclamationCircle = WithAudioPlayback.IconExclamationCircle;
28123
28062
  exports.IconExclamationCircle1 = WithAudioPlayback.IconExclamationCircle1;
28124
28063
  exports.IconExclamationTriangle = WithAudioPlayback.IconExclamationTriangle;
@@ -28248,6 +28187,7 @@ exports.isMessageBlocked = WithAudioPlayback.isMessageBlocked;
28248
28187
  exports.isMessageBounced = WithAudioPlayback.isMessageBounced;
28249
28188
  exports.isMessageEdited = WithAudioPlayback.isMessageEdited;
28250
28189
  exports.isMessageErrorRetryable = WithAudioPlayback.isMessageErrorRetryable;
28190
+ exports.isNetworkSendFailure = WithAudioPlayback.isNetworkSendFailure;
28251
28191
  exports.isNotificationForPanel = WithAudioPlayback.isNotificationForPanel;
28252
28192
  exports.isNotificationTargetPanel = WithAudioPlayback.isNotificationTargetPanel;
28253
28193
  exports.isNumberOrString = WithAudioPlayback.isNumberOrString;
@@ -28266,6 +28206,7 @@ exports.useActiveThread = WithAudioPlayback.useActiveThread;
28266
28206
  exports.useAudioPlayer = WithAudioPlayback.useAudioPlayer;
28267
28207
  exports.useChannelActionContext = WithAudioPlayback.useChannelActionContext;
28268
28208
  exports.useChannelEditMessageHandler = WithAudioPlayback.useEditMessageHandler;
28209
+ exports.useChannelListContext = WithAudioPlayback.useChannelListContext;
28269
28210
  exports.useChannelMentionsHandler = WithAudioPlayback.useMentionsHandlers;
28270
28211
  exports.useChannelStateContext = WithAudioPlayback.useChannelStateContext;
28271
28212
  exports.useChatContext = WithAudioPlayback.useChatContext;
@@ -28284,7 +28225,6 @@ exports.validateAndGetMessage = WithAudioPlayback.validateAndGetMessage;
28284
28225
  exports.AIStateIndicator = AIStateIndicator;
28285
28226
  exports.AIStates = AIStates;
28286
28227
  exports.ATTACHMENT_GROUPS_ORDER = ATTACHMENT_GROUPS_ORDER;
28287
- exports.ActionsIcon = ActionsIcon;
28288
28228
  exports.AddCommentPrompt = AddCommentPrompt;
28289
28229
  exports.Alert = Alert;
28290
28230
  exports.AmountBar = AmountBar;
@@ -28310,8 +28250,6 @@ exports.CardContainer = CardContainer;
28310
28250
  exports.ChannelAvatar = ChannelAvatar;
28311
28251
  exports.ChannelHeader = ChannelHeader;
28312
28252
  exports.ChannelList = ChannelList;
28313
- exports.ChannelListContext = ChannelListContext;
28314
- exports.ChannelListContextProvider = ChannelListContextProvider;
28315
28253
  exports.ChannelListItem = ChannelListItem;
28316
28254
  exports.ChannelListItemActionButtons = ChannelListItemActionButtons;
28317
28255
  exports.ChannelListItemTimestamp = ChannelListItemTimestamp;
@@ -28345,6 +28283,7 @@ exports.DurationDisplay = DurationDisplay;
28345
28283
  exports.EmojiContextMenuButton = EmojiContextMenuButton;
28346
28284
  exports.EmoticonItem = EmoticonItem;
28347
28285
  exports.EndPollAlert = EndPollAlert;
28286
+ exports.ErrorBadge = ErrorBadge;
28348
28287
  exports.EventComponent = EventComponent;
28349
28288
  exports.FILE_ICON_GRAPHIC_CLASSNAME = FILE_ICON_GRAPHIC_CLASSNAME;
28350
28289
  exports.FILE_ICON_NO_LABEL_CLASSNAME = FILE_ICON_NO_LABEL_CLASSNAME;
@@ -28393,7 +28332,6 @@ exports.MessageContext = MessageContext;
28393
28332
  exports.MessageDeletedBubble = MessageDeletedBubble;
28394
28333
  exports.MessageDeliveryStatus = MessageDeliveryStatus;
28395
28334
  exports.MessageEditedIndicator = MessageEditedIndicator;
28396
- exports.MessageErrorIcon = MessageErrorIcon;
28397
28335
  exports.MessageList = MessageList;
28398
28336
  exports.MessageListContext = MessageListContext;
28399
28337
  exports.MessageListContextProvider = MessageListContextProvider;
@@ -28421,7 +28359,6 @@ exports.NotificationTranslationTopic = NotificationTranslationTopic;
28421
28359
  exports.NumericInput = NumericInput;
28422
28360
  exports.OtherFilesContainer = OtherFilesContainer;
28423
28361
  exports.PauseIcon = PauseIcon;
28424
- exports.PinIcon = PinIcon;
28425
28362
  exports.PinIndicator = PinIndicator;
28426
28363
  exports.PlayButton = PlayButton;
28427
28364
  exports.PlayIcon = PlayIcon;
@@ -28448,7 +28385,6 @@ exports.QuotedMessage = QuotedMessage;
28448
28385
  exports.QuotedMessagePreview = QuotedMessagePreview;
28449
28386
  exports.QuotedMessagePreviewUI = QuotedMessagePreviewUI;
28450
28387
  exports.QuotedVoiceRecording = QuotedVoiceRecording;
28451
- exports.ReactionIcon = ReactionIcon;
28452
28388
  exports.ReactionSelector = ReactionSelector;
28453
28389
  exports.RecordingPermission = RecordingPermission;
28454
28390
  exports.RecordingPermissionDeniedNotification = RecordingPermissionDeniedNotification;
@@ -28488,7 +28424,6 @@ exports.TextInputFieldSet = TextInputFieldSet;
28488
28424
  exports.TextareaComposer = TextareaComposer;
28489
28425
  exports.Thread = Thread;
28490
28426
  exports.ThreadHeader = ThreadHeader;
28491
- exports.ThreadIcon = ThreadIcon;
28492
28427
  exports.ThreadList = ThreadList;
28493
28428
  exports.ThreadListItem = ThreadListItem;
28494
28429
  exports.ThreadListItemUI = ThreadListItemUI;
@@ -28596,7 +28531,6 @@ exports.useCanCreatePoll = useCanCreatePoll;
28596
28531
  exports.useChannelDeletedListener = useChannelDeletedListener;
28597
28532
  exports.useChannelDisplayName = useChannelDisplayName;
28598
28533
  exports.useChannelHiddenListener = useChannelHiddenListener;
28599
- exports.useChannelListContext = useChannelListContext;
28600
28534
  exports.useChannelListItemContext = useChannelListItemContext;
28601
28535
  exports.useChannelMembersState = useChannelMembersState;
28602
28536
  exports.useChannelMembershipState = useChannelMembershipState;