stream-chat-react 14.1.0 → 14.2.0

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 (44) hide show
  1. package/dist/cjs/emojis.js +1 -1
  2. package/dist/cjs/index.js +283 -51
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/{useNotificationApi.fd802923.js → useNotificationApi.f2c7704d.js} +4 -4
  5. package/dist/cjs/{useNotificationApi.fd802923.js.map → useNotificationApi.f2c7704d.js.map} +1 -1
  6. package/dist/css/index.css +163 -72
  7. package/dist/css/index.css.map +1 -1
  8. package/dist/es/emojis.mjs +1 -1
  9. package/dist/es/index.mjs +284 -52
  10. package/dist/es/index.mjs.map +1 -1
  11. package/dist/es/{useNotificationApi.e0c52de6.mjs → useNotificationApi.f91ae46b.mjs} +4 -4
  12. package/dist/es/{useNotificationApi.e0c52de6.mjs.map → useNotificationApi.f91ae46b.mjs.map} +1 -1
  13. package/dist/types/components/BaseImage/BaseImage.d.ts.map +1 -1
  14. package/dist/types/components/ChannelList/hooks/usePaginatedChannels.d.ts.map +1 -1
  15. package/dist/types/components/ChannelListItem/ChannelListItem.d.ts +2 -0
  16. package/dist/types/components/ChannelListItem/ChannelListItem.d.ts.map +1 -1
  17. package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.d.ts.map +1 -1
  18. package/dist/types/components/ChannelListItem/ChannelListItemUI.d.ts.map +1 -1
  19. package/dist/types/components/Form/Dropdown.d.ts +2 -1
  20. package/dist/types/components/Form/Dropdown.d.ts.map +1 -1
  21. package/dist/types/components/Message/MessageText.d.ts.map +1 -1
  22. package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts.map +1 -1
  23. package/dist/types/components/MessageComposer/AttachmentSelector/CommandsMenu.d.ts +2 -1
  24. package/dist/types/components/MessageComposer/AttachmentSelector/CommandsMenu.d.ts.map +1 -1
  25. package/dist/types/components/MessageComposer/EditedMessagePreview.d.ts.map +1 -1
  26. package/dist/types/components/MessageComposer/QuotedMessagePreview.d.ts +4 -2
  27. package/dist/types/components/MessageComposer/QuotedMessagePreview.d.ts.map +1 -1
  28. package/dist/types/components/MessageComposer/WithDragAndDropUpload.d.ts.map +1 -1
  29. package/dist/types/components/MessageComposer/hooks/index.d.ts +1 -0
  30. package/dist/types/components/MessageComposer/hooks/index.d.ts.map +1 -1
  31. package/dist/types/components/MessageComposer/hooks/useMessageComposerCommands.d.ts +9 -0
  32. package/dist/types/components/MessageComposer/hooks/useMessageComposerCommands.d.ts.map +1 -0
  33. package/dist/types/components/Reactions/ReactionSelector.d.ts.map +1 -1
  34. package/dist/types/components/TextareaComposer/SuggestionList/CommandItem.d.ts +1 -0
  35. package/dist/types/components/TextareaComposer/SuggestionList/CommandItem.d.ts.map +1 -1
  36. package/dist/types/components/TextareaComposer/SuggestionList/SuggestionList.d.ts.map +1 -1
  37. package/dist/types/components/TextareaComposer/TextareaComposer.d.ts +1 -0
  38. package/dist/types/components/TextareaComposer/TextareaComposer.d.ts.map +1 -1
  39. package/dist/types/i18n/Streami18n.d.ts +6 -0
  40. package/dist/types/i18n/Streami18n.d.ts.map +1 -1
  41. package/dist/types/i18n/TranslationBuilder/notifications/translators.d.ts +1 -0
  42. package/dist/types/i18n/TranslationBuilder/notifications/translators.d.ts.map +1 -1
  43. package/dist/types/i18n/TranslationBuilder/notifications/translatorsByNotificationType.d.ts.map +1 -1
  44. package/package.json +9 -5
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.56e5db9d.js");
8
- const useNotificationApi = require("./useNotificationApi.fd802923.js");
8
+ const useNotificationApi = require("./useNotificationApi.f2c7704d.js");
9
9
  const reactDom = require("react-dom");
10
10
  const streamChat = require("stream-chat");
11
11
  const sanitizeUrl = require("@braintree/sanitize-url");
@@ -981,7 +981,9 @@ const deTranslations = {
981
981
  "aria/Mark messages as read": "Nachrichten als gelesen markieren",
982
982
  "aria/Menu": "Menü",
983
983
  "aria/Message Actions": "Nachrichtenaktionen",
984
+ "aria/Message from {{ user }},": "Nachricht von {{ user }},",
984
985
  "aria/Message Options": "Nachrichtenoptionen",
986
+ "aria/Message,": "Nachricht,",
985
987
  "aria/Mute User": "Benutzer stummschalten",
986
988
  "aria/Notifications": "Benachrichtigungen",
987
989
  "aria/Open Attachment Selector": "Anhang-Auswahl öffnen",
@@ -1050,6 +1052,8 @@ const deTranslations = {
1050
1052
  "Close dialog": "Dialog schließen",
1051
1053
  "Close emoji picker": "Emoji-Auswahl schließen",
1052
1054
  "Close prompt: {{ title }}": "Eingabeaufforderung schließen: {{ title }}",
1055
+ "Command not available while editing": "Befehl beim Bearbeiten nicht verfügbar",
1056
+ "Command not available while replying": "Befehl beim Antworten nicht verfügbar",
1053
1057
  Commands: Commands$b,
1054
1058
  "Commands matching": "Übereinstimmende Befehle",
1055
1059
  "Connection failure, reconnecting now...": "Verbindungsfehler, Wiederherstellung der Verbindung...",
@@ -1109,6 +1113,8 @@ const deTranslations = {
1109
1113
  "Failed to end the poll due to {{reason}}": "Umfrage konnte aufgrund von {{reason}} nicht beendet werden",
1110
1114
  "Failed to jump to the first unread message": "Fehler beim Springen zur ersten ungelesenen Nachricht",
1111
1115
  "Failed to leave channel": "Kanal konnte nicht verlassen werden",
1116
+ "Failed to load channels": "Kanäle konnten nicht geladen werden",
1117
+ "Failed to load more channels": "Weitere Kanäle konnten nicht geladen werden",
1112
1118
  "Failed to mark channel as read": "Fehler beim Markieren des Kanals als gelesen",
1113
1119
  "Failed to play the recording": "Wiedergabe der Aufnahme fehlgeschlagen",
1114
1120
  "Failed to retrieve location": "Standort konnte nicht abgerufen werden",
@@ -1571,7 +1577,9 @@ const enTranslations = {
1571
1577
  "aria/Mark messages as read": "Mark messages as read",
1572
1578
  "aria/Menu": "Menu",
1573
1579
  "aria/Message Actions": "Message Actions",
1580
+ "aria/Message from {{ user }},": "Message from {{ user }},",
1574
1581
  "aria/Message Options": "Message Options",
1582
+ "aria/Message,": "Message,",
1575
1583
  "aria/Mute User": "Mute User",
1576
1584
  "aria/Notifications": "Notifications",
1577
1585
  "aria/Open Attachment Selector": "Open Attachment Selector",
@@ -1640,6 +1648,8 @@ const enTranslations = {
1640
1648
  "Close dialog": "Close dialog",
1641
1649
  "Close emoji picker": "Close emoji picker",
1642
1650
  "Close prompt: {{ title }}": "Close prompt: {{ title }}",
1651
+ "Command not available while editing": "Command not available while editing",
1652
+ "Command not available while replying": "Command not available while replying",
1643
1653
  Commands: Commands$a,
1644
1654
  "Commands matching": "Commands matching",
1645
1655
  "Connection failure, reconnecting now...": "Connection failure, reconnecting now...",
@@ -1699,6 +1709,8 @@ const enTranslations = {
1699
1709
  "Failed to end the poll due to {{reason}}": "Failed to end the poll due to {{reason}}",
1700
1710
  "Failed to jump to the first unread message": "Failed to jump to the first unread message",
1701
1711
  "Failed to leave channel": "Failed to leave channel",
1712
+ "Failed to load channels": "Failed to load channels",
1713
+ "Failed to load more channels": "Failed to load more channels",
1702
1714
  "Failed to mark channel as read": "Failed to mark channel as read",
1703
1715
  "Failed to play the recording": "Failed to play the recording",
1704
1716
  "Failed to retrieve location": "Failed to retrieve location",
@@ -2177,7 +2189,9 @@ const esTranslations = {
2177
2189
  "aria/Mark messages as read": "Marcar mensajes como leídos",
2178
2190
  "aria/Menu": "Menú",
2179
2191
  "aria/Message Actions": "Acciones del mensaje",
2192
+ "aria/Message from {{ user }},": "Mensaje de {{ user }},",
2180
2193
  "aria/Message Options": "Opciones de mensaje",
2194
+ "aria/Message,": "Mensaje,",
2181
2195
  "aria/Mute User": "Silenciar usuario",
2182
2196
  "aria/Notifications": "Notificaciones",
2183
2197
  "aria/Open Attachment Selector": "Abrir selector de adjuntos",
@@ -2246,6 +2260,8 @@ const esTranslations = {
2246
2260
  "Close dialog": "Cerrar diálogo",
2247
2261
  "Close emoji picker": "Cerrar el selector de emojis",
2248
2262
  "Close prompt: {{ title }}": "Cerrar diálogo: {{ title }}",
2263
+ "Command not available while editing": "Comando no disponible durante la edición",
2264
+ "Command not available while replying": "Comando no disponible mientras se responde",
2249
2265
  Commands: Commands$9,
2250
2266
  "Commands matching": "Coincidencia de comandos",
2251
2267
  "Connection failure, reconnecting now...": "Fallo de conexión, reconectando ahora...",
@@ -2305,6 +2321,8 @@ const esTranslations = {
2305
2321
  "Failed to end the poll due to {{reason}}": "No se pudo terminar la encuesta debido a {{reason}}",
2306
2322
  "Failed to jump to the first unread message": "Error al saltar al primer mensaje no leído",
2307
2323
  "Failed to leave channel": "No se pudo salir del canal",
2324
+ "Failed to load channels": "No se pudieron cargar los canales",
2325
+ "Failed to load more channels": "No se pudieron cargar más canales",
2308
2326
  "Failed to mark channel as read": "Error al marcar el canal como leído",
2309
2327
  "Failed to play the recording": "No se pudo reproducir la grabación",
2310
2328
  "Failed to retrieve location": "No se pudo obtener la ubicación",
@@ -2794,7 +2812,9 @@ const frTranslations = {
2794
2812
  "aria/Mark messages as read": "Marquer les messages comme lus",
2795
2813
  "aria/Menu": "Menu",
2796
2814
  "aria/Message Actions": "Actions du message",
2815
+ "aria/Message from {{ user }},": "Message de {{ user }},",
2797
2816
  "aria/Message Options": "Options du message",
2817
+ "aria/Message,": "Message,",
2798
2818
  "aria/Mute User": "Mettre en sourdine",
2799
2819
  "aria/Notifications": "Notifications",
2800
2820
  "aria/Open Attachment Selector": "Ouvrir le sélecteur de pièces jointes",
@@ -2863,6 +2883,8 @@ const frTranslations = {
2863
2883
  "Close dialog": "Fermer la boîte de dialogue",
2864
2884
  "Close emoji picker": "Fermer le sélecteur d'émojis",
2865
2885
  "Close prompt: {{ title }}": "Fermer l'invite : {{ title }}",
2886
+ "Command not available while editing": "Commande non disponible pendant la modification",
2887
+ "Command not available while replying": "Commande non disponible pendant la réponse",
2866
2888
  Commands: Commands$8,
2867
2889
  "Commands matching": "Correspondance des commandes",
2868
2890
  "Connection failure, reconnecting now...": "Échec de la connexion, reconnexion en cours...",
@@ -2922,6 +2944,8 @@ const frTranslations = {
2922
2944
  "Failed to end the poll due to {{reason}}": "Impossible de terminer le sondage en raison de {{reason}}",
2923
2945
  "Failed to jump to the first unread message": "Échec du saut vers le premier message non lu",
2924
2946
  "Failed to leave channel": "Impossible de quitter le canal",
2947
+ "Failed to load channels": "Impossible de charger les canaux",
2948
+ "Failed to load more channels": "Impossible de charger davantage de canaux",
2925
2949
  "Failed to mark channel as read": "Échec du marquage du canal comme lu",
2926
2950
  "Failed to play the recording": "Impossible de lire l'enregistrement",
2927
2951
  "Failed to retrieve location": "Impossible de récupérer l'emplacement",
@@ -3395,7 +3419,9 @@ const hiTranslations = {
3395
3419
  "aria/Mark messages as read": "संदेशों को पढ़ा हुआ चिह्नित करें",
3396
3420
  "aria/Menu": "मेन्यू",
3397
3421
  "aria/Message Actions": "संदेश कार्रवाइयाँ",
3422
+ "aria/Message from {{ user }},": "{{ user }} का संदेश,",
3398
3423
  "aria/Message Options": "संदेश विकल्प",
3424
+ "aria/Message,": "संदेश,",
3399
3425
  "aria/Mute User": "उपयोगकर्ता म्यूट करें",
3400
3426
  "aria/Notifications": "सूचनाएं",
3401
3427
  "aria/Open Attachment Selector": "अटैचमेंट चयनकर्ता खोलें",
@@ -3464,6 +3490,8 @@ const hiTranslations = {
3464
3490
  "Close dialog": "डायलॉग बंद करें",
3465
3491
  "Close emoji picker": "इमोजी पिकर बंद करें",
3466
3492
  "Close prompt: {{ title }}": "प्रॉम्प्ट बंद करें: {{ title }}",
3493
+ "Command not available while editing": "संपादन के दौरान कमांड उपलब्ध नहीं है",
3494
+ "Command not available while replying": "उत्तर देते समय कमांड उपलब्ध नहीं है",
3467
3495
  Commands: Commands$7,
3468
3496
  "Commands matching": "मेल खाती है",
3469
3497
  "Connection failure, reconnecting now...": "कनेक्शन विफल रहा, अब पुनः कनेक्ट हो रहा है ...",
@@ -3524,6 +3552,8 @@ const hiTranslations = {
3524
3552
  "Failed to end the poll due to {{reason}}": "{{reason}} के कारण पोल समाप्त करने में विफल",
3525
3553
  "Failed to jump to the first unread message": "पहले अपठित संदेश पर जाने में विफल",
3526
3554
  "Failed to leave channel": "चैनल छोड़ने में विफल",
3555
+ "Failed to load channels": "चैनल लोड करने में विफल",
3556
+ "Failed to load more channels": "और चैनल लोड करने में विफल",
3527
3557
  "Failed to mark channel as read": "चैनल को पढ़ा हुआ चिह्नित करने में विफल।",
3528
3558
  "Failed to play the recording": "रेकॉर्डिंग प्ले करने में विफल",
3529
3559
  "Failed to retrieve location": "स्थान प्राप्त करने में विफल",
@@ -4002,7 +4032,9 @@ const itTranslations = {
4002
4032
  "aria/Mark messages as read": "Segna i messaggi come letti",
4003
4033
  "aria/Menu": "Menu",
4004
4034
  "aria/Message Actions": "Azioni del messaggio",
4035
+ "aria/Message from {{ user }},": "Messaggio di {{ user }},",
4005
4036
  "aria/Message Options": "Opzioni di messaggio",
4037
+ "aria/Message,": "Messaggio,",
4006
4038
  "aria/Mute User": "Mute utente",
4007
4039
  "aria/Notifications": "Notifiche",
4008
4040
  "aria/Open Attachment Selector": "Apri selettore allegati",
@@ -4071,6 +4103,8 @@ const itTranslations = {
4071
4103
  "Close dialog": "Chiudi finestra di dialogo",
4072
4104
  "Close emoji picker": "Chiudi il selettore di emoji",
4073
4105
  "Close prompt: {{ title }}": "Chiudi prompt: {{ title }}",
4106
+ "Command not available while editing": "Comando non disponibile durante la modifica",
4107
+ "Command not available while replying": "Comando non disponibile durante la risposta",
4074
4108
  Commands: Commands$6,
4075
4109
  "Commands matching": "Comandi corrispondenti",
4076
4110
  "Connection failure, reconnecting now...": "Errore di connessione, riconnessione in corso...",
@@ -4130,6 +4164,8 @@ const itTranslations = {
4130
4164
  "Failed to end the poll due to {{reason}}": "Impossibile terminare il sondaggio a causa di {{reason}}",
4131
4165
  "Failed to jump to the first unread message": "Impossibile passare al primo messaggio non letto",
4132
4166
  "Failed to leave channel": "Impossibile lasciare il canale",
4167
+ "Failed to load channels": "Impossibile caricare i canali",
4168
+ "Failed to load more channels": "Impossibile caricare altri canali",
4133
4169
  "Failed to mark channel as read": "Impossibile contrassegnare il canale come letto",
4134
4170
  "Failed to play the recording": "Impossibile riprodurre la registrazione",
4135
4171
  "Failed to retrieve location": "Impossibile recuperare la posizione",
@@ -4596,7 +4632,9 @@ const jaTranslations = {
4596
4632
  "aria/Mark messages as read": "メッセージを既読にする",
4597
4633
  "aria/Menu": "メニュー",
4598
4634
  "aria/Message Actions": "メッセージ操作",
4635
+ "aria/Message from {{ user }},": "{{ user }}さんからのメッセージ,",
4599
4636
  "aria/Message Options": "メッセージオプション",
4637
+ "aria/Message,": "メッセージ,",
4600
4638
  "aria/Mute User": "ユーザーをミュート",
4601
4639
  "aria/Notifications": "通知",
4602
4640
  "aria/Open Attachment Selector": "添付ファイル選択を開く",
@@ -4665,6 +4703,8 @@ const jaTranslations = {
4665
4703
  "Close dialog": "ダイアログを閉じる",
4666
4704
  "Close emoji picker": "絵文字ピッカーを閉める",
4667
4705
  "Close prompt: {{ title }}": "プロンプトを閉じる: {{ title }}",
4706
+ "Command not available while editing": "編集中はコマンドを使用できません",
4707
+ "Command not available while replying": "返信中はコマンドを使用できません",
4668
4708
  Commands: Commands$5,
4669
4709
  "Commands matching": "一致するコマンド",
4670
4710
  "Connection failure, reconnecting now...": "接続が失敗しました。再接続中...",
@@ -4724,6 +4764,8 @@ const jaTranslations = {
4724
4764
  "Failed to end the poll due to {{reason}}": "{{reason}}のためアンケートの終了に失敗しました",
4725
4765
  "Failed to jump to the first unread message": "最初の未読メッセージにジャンプできませんでした",
4726
4766
  "Failed to leave channel": "チャンネルの退出に失敗しました",
4767
+ "Failed to load channels": "チャンネルの読み込みに失敗しました",
4768
+ "Failed to load more channels": "さらにチャンネルを読み込めませんでした",
4727
4769
  "Failed to mark channel as read": "チャンネルを既読にすることができませんでした",
4728
4770
  "Failed to play the recording": "録音の再生に失敗しました",
4729
4771
  "Failed to retrieve location": "位置情報の取得に失敗しました",
@@ -5172,7 +5214,9 @@ const koTranslations = {
5172
5214
  "aria/Mark messages as read": "메시지를 읽음으로 표시",
5173
5215
  "aria/Menu": "메뉴",
5174
5216
  "aria/Message Actions": "메시지 작업",
5217
+ "aria/Message from {{ user }},": "{{ user }}의 메시지,",
5175
5218
  "aria/Message Options": "메시지 옵션",
5219
+ "aria/Message,": "메시지,",
5176
5220
  "aria/Mute User": "사용자 음소거",
5177
5221
  "aria/Notifications": "알림",
5178
5222
  "aria/Open Attachment Selector": "첨부 파일 선택기 열기",
@@ -5241,6 +5285,8 @@ const koTranslations = {
5241
5285
  "Close dialog": "대화 상자 닫기",
5242
5286
  "Close emoji picker": "이모티콘 선택기 닫기",
5243
5287
  "Close prompt: {{ title }}": "프롬프트 닫기: {{ title }}",
5288
+ "Command not available while editing": "편집 중에는 명령을 사용할 수 없습니다",
5289
+ "Command not available while replying": "답장 중에는 명령을 사용할 수 없습니다",
5244
5290
  Commands: Commands$4,
5245
5291
  "Commands matching": "일치하는 명령",
5246
5292
  "Connection failure, reconnecting now...": "연결 실패, 지금 다시 연결 중...",
@@ -5300,6 +5346,8 @@ const koTranslations = {
5300
5346
  "Failed to end the poll due to {{reason}}": "{{reason}}(으)로 인해 투표 종료에 실패했습니다",
5301
5347
  "Failed to jump to the first unread message": "첫 번째 읽지 않은 메시지로 이동하지 못했습니다",
5302
5348
  "Failed to leave channel": "채널 나가기에 실패했습니다",
5349
+ "Failed to load channels": "채널을 불러오지 못했습니다",
5350
+ "Failed to load more channels": "채널을 더 불러오지 못했습니다",
5303
5351
  "Failed to mark channel as read": "채널을 읽음으로 표시하는 데 실패했습니다",
5304
5352
  "Failed to play the recording": "녹음을 재생하지 못했습니다",
5305
5353
  "Failed to retrieve location": "위치를 가져오지 못했습니다",
@@ -5755,7 +5803,9 @@ const nlTranslations = {
5755
5803
  "aria/Mark messages as read": "Markeer berichten als gelezen",
5756
5804
  "aria/Menu": "Menu",
5757
5805
  "aria/Message Actions": "Berichtacties",
5806
+ "aria/Message from {{ user }},": "Bericht van {{ user }},",
5758
5807
  "aria/Message Options": "Berichtopties",
5808
+ "aria/Message,": "Bericht,",
5759
5809
  "aria/Mute User": "Gebruiker dempen",
5760
5810
  "aria/Notifications": "Meldingen",
5761
5811
  "aria/Open Attachment Selector": "Open bijlage selector",
@@ -5824,6 +5874,8 @@ const nlTranslations = {
5824
5874
  "Close dialog": "Dialoog sluiten",
5825
5875
  "Close emoji picker": "Sluit de emoji-kiezer",
5826
5876
  "Close prompt: {{ title }}": "Prompt sluiten: {{ title }}",
5877
+ "Command not available while editing": "Opdracht niet beschikbaar tijdens bewerken",
5878
+ "Command not available while replying": "Opdracht niet beschikbaar tijdens beantwoorden",
5827
5879
  Commands: Commands$3,
5828
5880
  "Commands matching": "Bijpassende opdrachten",
5829
5881
  "Connection failure, reconnecting now...": "Verbindingsfout, opnieuw verbinden...",
@@ -5883,6 +5935,8 @@ const nlTranslations = {
5883
5935
  "Failed to end the poll due to {{reason}}": "Peiling kon niet worden beëindigd vanwege {{reason}}",
5884
5936
  "Failed to jump to the first unread message": "Niet gelukt om naar het eerste ongelezen bericht te springen",
5885
5937
  "Failed to leave channel": "Kanaal verlaten mislukt",
5938
+ "Failed to load channels": "Kanalen konden niet worden geladen",
5939
+ "Failed to load more channels": "Meer kanalen konden niet worden geladen",
5886
5940
  "Failed to mark channel as read": "Kanaal kon niet als gelezen worden gemarkeerd",
5887
5941
  "Failed to play the recording": "Kan de opname niet afspelen",
5888
5942
  "Failed to retrieve location": "Locatie kon niet worden opgehaald",
@@ -6363,7 +6417,9 @@ const ptTranslations = {
6363
6417
  "aria/Mark messages as read": "Marcar mensagens como lidas",
6364
6418
  "aria/Menu": "Menu",
6365
6419
  "aria/Message Actions": "Ações da mensagem",
6420
+ "aria/Message from {{ user }},": "Mensagem de {{ user }},",
6366
6421
  "aria/Message Options": "Opções de mensagem",
6422
+ "aria/Message,": "Mensagem,",
6367
6423
  "aria/Mute User": "Silenciar usuário",
6368
6424
  "aria/Notifications": "Notificações",
6369
6425
  "aria/Open Attachment Selector": "Abrir seletor de anexos",
@@ -6432,6 +6488,8 @@ const ptTranslations = {
6432
6488
  "Close dialog": "Fechar diálogo",
6433
6489
  "Close emoji picker": "Fechar seletor de emoji",
6434
6490
  "Close prompt: {{ title }}": "Fechar prompt: {{ title }}",
6491
+ "Command not available while editing": "Comando não disponível durante a edição",
6492
+ "Command not available while replying": "Comando não disponível durante a resposta",
6435
6493
  Commands: Commands$2,
6436
6494
  "Commands matching": "Comandos correspondentes",
6437
6495
  "Connection failure, reconnecting now...": "Falha de conexão, reconectando agora...",
@@ -6491,6 +6549,8 @@ const ptTranslations = {
6491
6549
  "Failed to end the poll due to {{reason}}": "Falha ao encerrar a enquete devido a {{reason}}",
6492
6550
  "Failed to jump to the first unread message": "Falha ao pular para a primeira mensagem não lida",
6493
6551
  "Failed to leave channel": "Falha ao sair do canal",
6552
+ "Failed to load channels": "Falha ao carregar os canais",
6553
+ "Failed to load more channels": "Falha ao carregar mais canais",
6494
6554
  "Failed to mark channel as read": "Falha ao marcar o canal como lido",
6495
6555
  "Failed to play the recording": "Falha ao reproduzir a gravação",
6496
6556
  "Failed to retrieve location": "Falha ao obter localização",
@@ -7000,7 +7060,9 @@ const ruTranslations = {
7000
7060
  "aria/Mark messages as read": "Отметить сообщения как прочитанные",
7001
7061
  "aria/Menu": "Меню",
7002
7062
  "aria/Message Actions": "Действия с сообщением",
7063
+ "aria/Message from {{ user }},": "Сообщение от {{ user }},",
7003
7064
  "aria/Message Options": "Параметры сообщения",
7065
+ "aria/Message,": "Сообщение,",
7004
7066
  "aria/Mute User": "Отключить уведомления",
7005
7067
  "aria/Notifications": "Уведомления",
7006
7068
  "aria/Open Attachment Selector": "Открыть выбор вложений",
@@ -7069,6 +7131,8 @@ const ruTranslations = {
7069
7131
  "Close dialog": "Закрыть диалог",
7070
7132
  "Close emoji picker": "Закрыть окно выбора смайлов",
7071
7133
  "Close prompt: {{ title }}": "Закрыть запрос: {{ title }}",
7134
+ "Command not available while editing": "Команда недоступна при редактировании",
7135
+ "Command not available while replying": "Команда недоступна при ответе",
7072
7136
  Commands: Commands$1,
7073
7137
  "Commands matching": "Соответствие команд",
7074
7138
  "Connection failure, reconnecting now...": "Ошибка соединения, переподключение...",
@@ -7128,6 +7192,8 @@ const ruTranslations = {
7128
7192
  "Failed to end the poll due to {{reason}}": "Не удалось завершить опрос из-за {{reason}}",
7129
7193
  "Failed to jump to the first unread message": "Не удалось перейти к первому непрочитанному сообщению",
7130
7194
  "Failed to leave channel": "Не удалось покинуть канал",
7195
+ "Failed to load channels": "Не удалось загрузить каналы",
7196
+ "Failed to load more channels": "Не удалось загрузить больше каналов",
7131
7197
  "Failed to mark channel as read": "Не удалось пометить канал как прочитанный",
7132
7198
  "Failed to play the recording": "Не удалось воспроизвести запись",
7133
7199
  "Failed to retrieve location": "Не удалось получить местоположение",
@@ -7615,7 +7681,9 @@ const trTranslations = {
7615
7681
  "aria/Mark messages as read": "Mesajları okundu olarak işaretle",
7616
7682
  "aria/Menu": "Menü",
7617
7683
  "aria/Message Actions": "Mesaj eylemleri",
7684
+ "aria/Message from {{ user }},": "{{ user }} adlı kullanıcıdan mesaj,",
7618
7685
  "aria/Message Options": "Mesaj Seçenekleri",
7686
+ "aria/Message,": "Mesaj,",
7619
7687
  "aria/Mute User": "Kullanıcıyı sustur",
7620
7688
  "aria/Notifications": "Bildirimler",
7621
7689
  "aria/Open Attachment Selector": "Ek Seçiciyi Aç",
@@ -7684,6 +7752,8 @@ const trTranslations = {
7684
7752
  "Close dialog": "İletişim kutusunu kapat",
7685
7753
  "Close emoji picker": "Emoji seçiciyi kapat",
7686
7754
  "Close prompt: {{ title }}": "İstemi kapat: {{ title }}",
7755
+ "Command not available while editing": "Düzenleme sırasında komut kullanılamaz",
7756
+ "Command not available while replying": "Yanıtlama sırasında komut kullanılamaz",
7687
7757
  Commands,
7688
7758
  "Commands matching": "Eşleşen komutlar",
7689
7759
  "Connection failure, reconnecting now...": "Bağlantı hatası, tekrar bağlanılıyor...",
@@ -7743,6 +7813,8 @@ const trTranslations = {
7743
7813
  "Failed to end the poll due to {{reason}}": "{{reason}} nedeniyle anket sonlandırılamadı",
7744
7814
  "Failed to jump to the first unread message": "İlk okunmamış mesaja atlamada hata oluştu",
7745
7815
  "Failed to leave channel": "Kanaldan çıkılamadı",
7816
+ "Failed to load channels": "Kanallar yüklenemedi",
7817
+ "Failed to load more channels": "Daha fazla kanal yüklenemedi",
7746
7818
  "Failed to mark channel as read": "Kanalı okundu olarak işaretleme başarısız oldu",
7747
7819
  "Failed to play the recording": "Kayıt oynatılamadı",
7748
7820
  "Failed to retrieve location": "Konum alınamadı",
@@ -8607,6 +8679,19 @@ const translatePollEndFailed = ({
8607
8679
  t
8608
8680
  });
8609
8681
  const translateBrowserAudioPlaybackError = ({ options: { notification }, t }) => notification?.message ? t(notification.message) : t("Error reproducing the recording");
8682
+ const translateCommandDisabled = ({
8683
+ options: { notification },
8684
+ t
8685
+ }) => {
8686
+ const reason = normalizeReason(notification);
8687
+ if (reason === "editing") {
8688
+ return t("Command not available while editing");
8689
+ }
8690
+ if (reason === "quoted_message") {
8691
+ return t("Command not available while replying");
8692
+ }
8693
+ return t(notification?.message || "Command not available");
8694
+ };
8610
8695
  const translatorsByNotificationType = {
8611
8696
  "api:attachment:upload:failed": translateAttachmentUploadFailed,
8612
8697
  "api:location:create:failed": ({ t }) => t("Failed to share location"),
@@ -8622,6 +8707,7 @@ const translatorsByNotificationType = {
8622
8707
  "validation:attachment:id:missing": ({ t }) => t("Local upload attachment missing local id"),
8623
8708
  "validation:attachment:upload:blocked": translateAttachmentUploadBlocked,
8624
8709
  "validation:attachment:upload:in-progress": ({ t }) => t("Wait until all attachments have uploaded"),
8710
+ "validation:command:disabled": translateCommandDisabled,
8625
8711
  "validation:poll:castVote:limit": ({ t }) => t("Reached the vote limit. Remove an existing vote first.")
8626
8712
  };
8627
8713
  const translateByNotificationType = ({
@@ -10047,7 +10133,7 @@ const DialogAnchor = ({
10047
10133
  React.useEffect(() => {
10048
10134
  if (!open) return;
10049
10135
  const hideOnEscape = (event) => {
10050
- if (event.key !== "Escape") return;
10136
+ if (event.key !== "Escape" || event.defaultPrevented) return;
10051
10137
  dialog?.close();
10052
10138
  };
10053
10139
  document.addEventListener("keyup", hideOnEscape);
@@ -10152,7 +10238,7 @@ const Avatar = ({
10152
10238
  }
10153
10239
  return initials;
10154
10240
  }, [nameString, size]);
10155
- const showImage = typeof imageUrl === "string" && !error;
10241
+ const showImage = typeof imageUrl === "string" && imageUrl && !error;
10156
10242
  return /* @__PURE__ */ jsxRuntime.jsxs(
10157
10243
  "div",
10158
10244
  {
@@ -12075,9 +12161,11 @@ const UnMemoizedMessageTextComponent = (props) => {
12075
12161
  unsafeHTML
12076
12162
  } = useMessageContext();
12077
12163
  const renderText$1 = propsRenderText ?? contextRenderText ?? renderText;
12078
- const { userLanguage } = useNotificationApi.useTranslationContext("MessageText");
12164
+ const { t, userLanguage } = useNotificationApi.useTranslationContext("MessageText");
12079
12165
  const message = propMessage || contextMessage;
12080
12166
  const hasAttachment = useNotificationApi.messageHasAttachments(message);
12167
+ const messageContextId = React.useId();
12168
+ const messageTextId = React.useId();
12081
12169
  const messageTextToRender = translationView === "original" ? message.text : getTranslatedMessageText({ language: userLanguage, message }) || message.text;
12082
12170
  const messageText = React.useMemo(
12083
12171
  () => renderText$1(messageTextToRender, message.mentioned_users),
@@ -12087,6 +12175,9 @@ const UnMemoizedMessageTextComponent = (props) => {
12087
12175
  const innerClass = customInnerClass;
12088
12176
  const hasMentionedUsers = Boolean(message.mentioned_users?.length);
12089
12177
  const isMentionsInteractionEnabled = hasMentionedUsers && typeof onMentionsClickMessage === "function";
12178
+ const senderName = message.user?.name;
12179
+ const messageContext = senderName ? t("aria/Message from {{ user }},", { user: senderName }) : t("aria/Message,");
12180
+ const messageLabelledBy = `${messageContextId} ${messageTextId}`;
12090
12181
  const handleMentionsKeyDown = (event) => {
12091
12182
  if (!isMentionsInteractionEnabled || event.key !== "Enter" && event.key !== " ") {
12092
12183
  return;
@@ -12095,21 +12186,33 @@ const UnMemoizedMessageTextComponent = (props) => {
12095
12186
  onMentionsClickMessage(event);
12096
12187
  };
12097
12188
  if (!messageTextToRender) return null;
12098
- return /* @__PURE__ */ jsxRuntime.jsx("div", { className: wrapperClass, tabIndex: isMentionsInteractionEnabled ? void 0 : 0, children: /* @__PURE__ */ jsxRuntime.jsx(
12189
+ return /* @__PURE__ */ jsxRuntime.jsxs(
12099
12190
  "div",
12100
12191
  {
12101
- className: clsx(innerClass, {
12102
- [` str-chat__message-text-inner--is-emoji`]: useNotificationApi.messageTextHasEmojisOnly(message) && !message.quoted_message,
12103
- [`str-chat__message-text-inner--has-attachment`]: hasAttachment
12104
- }),
12105
- "data-testid": "message-text-inner-wrapper",
12106
- onClick: onMentionsClickMessage,
12107
- onKeyDown: isMentionsInteractionEnabled ? handleMentionsKeyDown : void 0,
12108
- onMouseOver: onMentionsHoverMessage,
12109
- tabIndex: isMentionsInteractionEnabled ? 0 : void 0,
12110
- children: unsafeHTML && message.html ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: message.html } }) : /* @__PURE__ */ jsxRuntime.jsx("div", { children: messageText })
12192
+ "aria-labelledby": isMentionsInteractionEnabled ? void 0 : messageLabelledBy,
12193
+ className: wrapperClass,
12194
+ tabIndex: isMentionsInteractionEnabled ? void 0 : 0,
12195
+ children: [
12196
+ /* @__PURE__ */ jsxRuntime.jsx(VisuallyHidden, { id: messageContextId, children: messageContext }),
12197
+ /* @__PURE__ */ jsxRuntime.jsx(
12198
+ "div",
12199
+ {
12200
+ "aria-labelledby": isMentionsInteractionEnabled ? messageLabelledBy : void 0,
12201
+ className: clsx(innerClass, {
12202
+ [` str-chat__message-text-inner--is-emoji`]: useNotificationApi.messageTextHasEmojisOnly(message) && !message.quoted_message,
12203
+ [`str-chat__message-text-inner--has-attachment`]: hasAttachment
12204
+ }),
12205
+ "data-testid": "message-text-inner-wrapper",
12206
+ onClick: onMentionsClickMessage,
12207
+ onKeyDown: isMentionsInteractionEnabled ? handleMentionsKeyDown : void 0,
12208
+ onMouseOver: onMentionsHoverMessage,
12209
+ tabIndex: isMentionsInteractionEnabled ? 0 : void 0,
12210
+ children: unsafeHTML && message.html ? /* @__PURE__ */ jsxRuntime.jsx("div", { dangerouslySetInnerHTML: { __html: message.html }, id: messageTextId }) : /* @__PURE__ */ jsxRuntime.jsx("div", { id: messageTextId, children: messageText })
12211
+ }
12212
+ )
12213
+ ]
12111
12214
  }
12112
- ) });
12215
+ );
12113
12216
  };
12114
12217
  const MessageText = React.memo(
12115
12218
  UnMemoizedMessageTextComponent
@@ -13890,12 +13993,13 @@ const BaseImage = React.forwardRef(function BaseImage2({ src, ...props }, ref) {
13890
13993
  showDownloadButtonOnError = false,
13891
13994
  ...imgProps
13892
13995
  } = props;
13893
- const [error, setError] = React.useState(false);
13996
+ const [failedSrc, setFailedSrc] = React.useState(null);
13894
13997
  const { ImagePlaceholder: ImagePlaceholderComponent = ImagePlaceholder } = useNotificationApi.useComponentContext();
13895
13998
  const sanitizedUrl = React.useMemo(() => sanitizeUrl.sanitizeUrl(src), [src]);
13999
+ const error = failedSrc === sanitizedUrl;
13896
14000
  React.useEffect(
13897
14001
  () => () => {
13898
- setError(false);
14002
+ setFailedSrc(null);
13899
14003
  },
13900
14004
  [sanitizedUrl]
13901
14005
  );
@@ -13918,7 +14022,7 @@ const BaseImage = React.forwardRef(function BaseImage2({ src, ...props }, ref) {
13918
14022
  alt: propsAlt ?? "",
13919
14023
  className: clsx(propsClassName, "str-chat__base-image"),
13920
14024
  onError: (e) => {
13921
- setError(true);
14025
+ setFailedSrc(sanitizedUrl);
13922
14026
  propsOnError?.(e);
13923
14027
  },
13924
14028
  ref,
@@ -14464,7 +14568,7 @@ const ThumbnailButton = ({
14464
14568
  const imageUrl = item.imageUrl;
14465
14569
  const [isLoadFailed, setIsLoadFailed] = React.useState(false);
14466
14570
  const [isImageLoading, setIsImageLoading] = React.useState(Boolean(imageUrl));
14467
- const [retryCount, setRetryCount] = React.useState(0);
14571
+ const [retrySuffix, setRetrySuffix] = React.useState("");
14468
14572
  const {
14469
14573
  onError: itemOnError,
14470
14574
  onLoad: itemOnLoad,
@@ -14476,7 +14580,7 @@ const ThumbnailButton = ({
14476
14580
  if (showRetryIndicator) {
14477
14581
  setIsLoadFailed(false);
14478
14582
  setIsImageLoading(true);
14479
- setRetryCount((currentRetryCount) => currentRetryCount + 1);
14583
+ setRetrySuffix(`&retry=${Date.now()}`);
14480
14584
  return;
14481
14585
  }
14482
14586
  onClick();
@@ -14508,10 +14612,9 @@ const ThumbnailButton = ({
14508
14612
  setIsLoadFailed(false);
14509
14613
  itemOnLoad?.(event);
14510
14614
  },
14511
- src: imageUrl,
14615
+ src: imageUrl ? `${imageUrl}${retrySuffix}` : imageUrl,
14512
14616
  ...baseImageUsesDefaultBehavior ? { showDownloadButtonOnError: false } : {}
14513
- },
14514
- retryCount
14617
+ }
14515
14618
  ),
14516
14619
  showLoadingIndicator && /* @__PURE__ */ jsxRuntime.jsx(
14517
14620
  "div",
@@ -16187,6 +16290,32 @@ const useMessageComposerBindings = (props) => {
16187
16290
  textareaRef
16188
16291
  };
16189
16292
  };
16293
+ const messageComposerStateSelector$4 = ({
16294
+ editedMessage,
16295
+ quotedMessage
16296
+ }) => ({
16297
+ editedMessage,
16298
+ quotedMessage
16299
+ });
16300
+ const useMessageComposerCommands = () => {
16301
+ const messageComposer = useNotificationApi.useMessageComposerController();
16302
+ const channelConfig = messageComposer.channel.getConfig();
16303
+ const { editedMessage, quotedMessage } = useNotificationApi.useStateStore(
16304
+ messageComposer.state,
16305
+ messageComposerStateSelector$4
16306
+ );
16307
+ return React.useMemo(
16308
+ () => (channelConfig?.commands ?? []).filter(
16309
+ (command) => !!command.name
16310
+ ).map((command) => ({
16311
+ command,
16312
+ enabled: !messageComposer.isCommandDisabled(command)
16313
+ })),
16314
+ // editedMessage and quotedMessage are necessary in deps for reactivity
16315
+ // eslint-disable-next-line react-hooks/exhaustive-deps
16316
+ [channelConfig, editedMessage, messageComposer, quotedMessage]
16317
+ );
16318
+ };
16190
16319
  const editingAuditStateStateSelector$1 = (state) => state;
16191
16320
  const useMessageComposerHasSendableData = () => {
16192
16321
  const messageComposer = useNotificationApi.useMessageComposerController();
@@ -16426,6 +16555,8 @@ const QuotedMessagePreview = ({
16426
16555
  ) }) : null;
16427
16556
  };
16428
16557
  const QuotedMessagePreviewUI = ({
16558
+ authorLabel,
16559
+ className,
16429
16560
  getQuotedMessageAuthor,
16430
16561
  onClick,
16431
16562
  onRemove,
@@ -16502,7 +16633,7 @@ const QuotedMessagePreviewUI = ({
16502
16633
  "div",
16503
16634
  {
16504
16635
  "aria-label": isInteractive ? t("aria/Jump to quoted message") : void 0,
16505
- className: clsx("str-chat__quoted-message-preview", {
16636
+ className: clsx("str-chat__quoted-message-preview", className, {
16506
16637
  "str-chat__quoted-message-preview--own": isOwnMessage
16507
16638
  }),
16508
16639
  "data-testid": "quoted-message-preview",
@@ -16513,7 +16644,7 @@ const QuotedMessagePreviewUI = ({
16513
16644
  children: [
16514
16645
  /* @__PURE__ */ jsxRuntime.jsx(QuotedMessageIndicator, { isOwnMessage }),
16515
16646
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__quoted-message-preview__content", children: [
16516
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__quoted-message-preview__author", children: isOwnMessage ? t("You") : authorName ? t("Reply to {{ authorName }}", { authorName }) : t("Reply") }),
16647
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "str-chat__quoted-message-preview__author", children: authorLabel ?? (isOwnMessage ? t("You") : authorName ? t("Reply to {{ authorName }}", { authorName }) : t("Reply")) }),
16517
16648
  /* @__PURE__ */ jsxRuntime.jsxs(
16518
16649
  "div",
16519
16650
  {
@@ -16651,6 +16782,7 @@ const StreamedMessageText = (props) => {
16651
16782
  );
16652
16783
  };
16653
16784
  const DEFAULT_DROPDOWN_ITEM_SELECTOR = '[role="option"]:not(:disabled), [role="menuitem"]:not(:disabled), button:not(:disabled), a:not(:disabled)';
16785
+ const isEditableTarget = (target) => target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
16654
16786
  const DropdownContext = React.createContext({
16655
16787
  close: () => null
16656
16788
  });
@@ -16662,6 +16794,7 @@ const useDropdownContext = () => React.useContext(DropdownContext);
16662
16794
  const Dropdown = ({
16663
16795
  children,
16664
16796
  className,
16797
+ matchReferenceWidth = false,
16665
16798
  onClose,
16666
16799
  onOpen,
16667
16800
  placement = "bottom",
@@ -16728,17 +16861,29 @@ const Dropdown = ({
16728
16861
  }),
16729
16862
  []
16730
16863
  );
16864
+ const escapeConsumedRef = React.useRef(false);
16731
16865
  const handleKeyDown = React.useCallback(
16732
16866
  (event) => {
16733
16867
  if (event.key === "Escape") {
16734
16868
  event.preventDefault();
16869
+ event.stopPropagation();
16870
+ escapeConsumedRef.current = true;
16735
16871
  close();
16736
16872
  return;
16737
16873
  }
16874
+ if (isEditableTarget(event.target)) {
16875
+ return;
16876
+ }
16738
16877
  rovingFocusKeyDownHandler(event);
16739
16878
  },
16740
16879
  [close, rovingFocusKeyDownHandler]
16741
16880
  );
16881
+ const suppressEscapeKeyUp = React.useCallback((event) => {
16882
+ if (event.key === "Escape" && escapeConsumedRef.current) {
16883
+ escapeConsumedRef.current = false;
16884
+ event.stopPropagation();
16885
+ }
16886
+ }, []);
16742
16887
  const DropdownTriggerComponent = TriggerComponent;
16743
16888
  const trigger = DropdownTriggerComponent ? /* @__PURE__ */ jsxRuntime.jsx(
16744
16889
  DropdownTriggerComponent,
@@ -16755,10 +16900,12 @@ const Dropdown = ({
16755
16900
  className: clsx("str-chat__dropdown__items", className),
16756
16901
  onClick: close,
16757
16902
  onKeyDown: handleKeyDown,
16903
+ onKeyUpCapture: suppressEscapeKeyUp,
16758
16904
  ref: setFloatingElement,
16759
16905
  role: "menu",
16760
16906
  style: {
16761
16907
  left: x ?? 0,
16908
+ minWidth: matchReferenceWidth ? resolvedReferenceElement.getBoundingClientRect().width : void 0,
16762
16909
  position: strategy,
16763
16910
  top: y ?? 0
16764
16911
  },
@@ -19159,19 +19306,20 @@ const CommandsMenu = () => {
19159
19306
  const { closeMenu } = useContextMenuContext();
19160
19307
  const messageComposer = useNotificationApi.useMessageComposerController();
19161
19308
  const { textareaRef } = useNotificationApi.useMessageComposerContext();
19162
- const channelConfig = messageComposer.channel.getConfig();
19163
- const commands = React.useMemo(
19164
- () => (channelConfig?.commands ?? []).filter(
19165
- (command) => !!command.name
19166
- ).sort((a, b) => (a.name ?? "").localeCompare(b.name ?? "")),
19167
- [channelConfig]
19309
+ const commands = useMessageComposerCommands();
19310
+ const sortedCommands = React.useMemo(
19311
+ () => [...commands].sort(
19312
+ (a, b) => (a.command.name ?? "").localeCompare(b.command.name ?? "")
19313
+ ),
19314
+ [commands]
19168
19315
  );
19169
- return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: commands.map((command) => /* @__PURE__ */ jsxRuntime.jsx(
19316
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: sortedCommands.map(({ command, enabled }) => /* @__PURE__ */ jsxRuntime.jsx(
19170
19317
  CommandContextMenuItem,
19171
19318
  {
19172
19319
  command,
19320
+ enabled,
19173
19321
  onClick: () => {
19174
- if (!command.name) return;
19322
+ if (!command.name || !enabled) return;
19175
19323
  messageComposer.textComposer.setCommand(command);
19176
19324
  closeMenu();
19177
19325
  requestAnimationFrame(() => textareaRef.current?.focus());
@@ -19209,16 +19357,21 @@ const useCommandTranslation = (command) => {
19209
19357
  const CommandContextMenuItem = ({
19210
19358
  className,
19211
19359
  command,
19360
+ enabled = true,
19212
19361
  ...props
19213
19362
  }) => {
19214
19363
  const { args, description } = useCommandTranslation(command);
19215
- const details = React.useMemo(() => `/${command.name} ${args}`, [args, command.name]);
19364
+ const details = React.useMemo(
19365
+ () => args ? `/${command.name} ${args}` : `/${command.name}`,
19366
+ [args, command.name]
19367
+ );
19216
19368
  return /* @__PURE__ */ React.createElement(
19217
19369
  ContextMenuButton,
19218
19370
  {
19219
19371
  ...props,
19220
19372
  className: clsx("str-chat__context-menu__button--command", className),
19221
19373
  details,
19374
+ disabled: !enabled,
19222
19375
  Icon: icons[command.name],
19223
19376
  key: command.name,
19224
19377
  label: command.name,
@@ -19291,11 +19444,14 @@ const DefaultAttachmentSelectorComponents = {
19291
19444
  Command({ submenuHeader, submenuItems }) {
19292
19445
  const { t } = useNotificationApi.useTranslationContext();
19293
19446
  const { openSubmenu } = useContextMenuContext();
19447
+ const commands = useMessageComposerCommands();
19448
+ const hasEnabledCommands = commands.some(({ enabled }) => enabled);
19294
19449
  const hasSubmenu = !!submenuItems;
19295
19450
  return /* @__PURE__ */ jsxRuntime.jsx(
19296
19451
  ContextMenuButton,
19297
19452
  {
19298
- className: "str-chat__attachment-selector-actions-menu__button str-chat__attachment-selector-actions-menu__create-poll-button",
19453
+ className: "str-chat__attachment-selector-actions-menu__button str-chat__attachment-selector-actions-menu__commands-button",
19454
+ disabled: !hasEnabledCommands,
19299
19455
  hasSubMenu: hasSubmenu,
19300
19456
  Icon: useNotificationApi.IconCommand,
19301
19457
  onClick: (event) => {
@@ -20597,7 +20753,17 @@ const DefaultStartRecordingAudioButton = React.forwardRef(function StartRecordin
20597
20753
  const EditedMessagePreview = ({
20598
20754
  message,
20599
20755
  onCancel
20600
- }) => /* @__PURE__ */ jsxRuntime.jsx(QuotedMessagePreviewUI, { onRemove: onCancel, quotedMessage: message });
20756
+ }) => {
20757
+ const { t } = useNotificationApi.useTranslationContext();
20758
+ return /* @__PURE__ */ jsxRuntime.jsx(
20759
+ QuotedMessagePreviewUI,
20760
+ {
20761
+ authorLabel: t("Edit Message"),
20762
+ onRemove: onCancel,
20763
+ quotedMessage: message
20764
+ }
20765
+ );
20766
+ };
20601
20767
  const stateSelector = (state) => ({
20602
20768
  showReplyInChannel: state.showReplyInChannel
20603
20769
  });
@@ -20639,14 +20805,25 @@ const SendToChannelCheckbox = () => {
20639
20805
  }
20640
20806
  );
20641
20807
  };
20808
+ const messageComposerStateSelector$3 = ({
20809
+ editedMessage,
20810
+ quotedMessage
20811
+ }) => ({
20812
+ editedMessage,
20813
+ quotedMessage
20814
+ });
20642
20815
  const CommandItem = (props) => {
20643
- const { entity, focused: _, ...buttonProps } = props;
20816
+ const { enabled, entity, focused: _, ...buttonProps } = props;
20817
+ const messageComposer = useNotificationApi.useMessageComposerController();
20818
+ useNotificationApi.useStateStore(messageComposer.state, messageComposerStateSelector$3);
20644
20819
  if (!entity.name) return null;
20820
+ const resolvedEnabled = enabled ?? !messageComposer.isCommandDisabled(entity);
20645
20821
  return /* @__PURE__ */ jsxRuntime.jsx(
20646
20822
  CommandContextMenuItem,
20647
20823
  {
20648
20824
  ...buttonProps,
20649
- command: entity
20825
+ command: entity,
20826
+ enabled: resolvedEnabled
20650
20827
  }
20651
20828
  );
20652
20829
  };
@@ -20804,12 +20981,17 @@ const SuggestionList = ({
20804
20981
  } = useNotificationApi.useComponentContext();
20805
20982
  const { textareaRef } = useNotificationApi.useMessageComposerContext();
20806
20983
  const messageComposer = useNotificationApi.useMessageComposerController();
20984
+ const commands = useMessageComposerCommands();
20807
20985
  const { textComposer } = messageComposer;
20808
20986
  const { selection, suggestions } = useNotificationApi.useStateStore(
20809
20987
  textComposer.state,
20810
20988
  textComposerStateSelector$3
20811
20989
  );
20812
20990
  const { items } = useNotificationApi.useStateStore(suggestions?.searchSource.state, searchSourceStateSelector$5) ?? {};
20991
+ const hasEnabledCommandSuggestions = React.useMemo(
20992
+ () => suggestions?.searchSource.type !== "commands" || commands.some(({ enabled }) => enabled),
20993
+ [commands, suggestions?.searchSource.type]
20994
+ );
20813
20995
  const [container, setContainer] = React.useState(null);
20814
20996
  const caretRectRef = React.useRef(null);
20815
20997
  const virtualCaretReference = React.useMemo(
@@ -20905,7 +21087,8 @@ const SuggestionList = ({
20905
21087
  update,
20906
21088
  virtualCaretReference
20907
21089
  ]);
20908
- if (!suggestions || !items?.length || !component) return null;
21090
+ if (!suggestions || !items?.length || !component || !hasEnabledCommandSuggestions)
21091
+ return null;
20909
21092
  const suggestionMenuLabel = suggestions.searchSource.type === "commands" ? t("aria/Command Suggestions") : suggestions.searchSource.type === "emojis" ? t("aria/Emoji Suggestions") : suggestions.searchSource.type === "mentions" ? t("aria/User Suggestions") : t("aria/Suggestions");
20910
21093
  return /* @__PURE__ */ jsxRuntime.jsx(
20911
21094
  "div",
@@ -20982,6 +21165,7 @@ const attachmentManagerStateSelector$1 = (state) => ({
20982
21165
  attachments: state.attachments
20983
21166
  });
20984
21167
  const defaultShouldSubmit = (event) => event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing;
21168
+ const shouldBackspaceExitCommandMode = (text2) => text2.length === 0;
20985
21169
  const TextareaComposer = ({
20986
21170
  className,
20987
21171
  closeSuggestionsOnClickOutside,
@@ -21068,6 +21252,7 @@ const TextareaComposer = ({
21068
21252
  onKeyDown(event);
21069
21253
  return;
21070
21254
  }
21255
+ const textareaValue = textareaRef.current?.value ?? event.currentTarget.value;
21071
21256
  if (textComposer.suggestions && textComposer.suggestions.searchSource.items?.length) {
21072
21257
  if (event.key === "Escape") return textComposer.closeSuggestions();
21073
21258
  const loadedItems = textComposer.suggestions.searchSource.items;
@@ -21099,6 +21284,9 @@ const TextareaComposer = ({
21099
21284
  return nextIndex;
21100
21285
  });
21101
21286
  }
21287
+ } else if (textComposer.command && (event.key === "Escape" || event.key === "Backspace" && shouldBackspaceExitCommandMode(textareaValue))) {
21288
+ event.preventDefault();
21289
+ textComposer.clearCommand();
21102
21290
  } else if (shouldSubmit(event) && textareaRef.current && messageComposer.hasSendableData) {
21103
21291
  if (event.key === "Enter") {
21104
21292
  event.preventDefault();
@@ -21269,6 +21457,7 @@ const WithDragAndDropUpload = ({
21269
21457
  disabled: isWithinMessageComposerContext ? !isUploadEnabled || isCooldownActive : false,
21270
21458
  multiple: multipleUploads,
21271
21459
  noClick: true,
21460
+ noKeyboard: true,
21272
21461
  onDrop: isWithinMessageComposerContext ? messageComposer.attachmentManager.uploadFiles : handleDrop
21273
21462
  });
21274
21463
  if (dragAndDropUploadContext.subscribeToDrop !== null) {
@@ -22236,6 +22425,7 @@ const ReactionSelector = (props) => {
22236
22425
  })
22237
22426
  );
22238
22427
  }, [reactionOptions]);
22428
+ const hasExtendedReactions = !Array.isArray(reactionOptions) && reactionOptions.extended && Object.keys(reactionOptions.extended).length > 0;
22239
22429
  return /* @__PURE__ */ jsxRuntime.jsx(
22240
22430
  "div",
22241
22431
  {
@@ -22273,7 +22463,7 @@ const ReactionSelector = (props) => {
22273
22463
  )
22274
22464
  }
22275
22465
  ),
22276
- /* @__PURE__ */ jsxRuntime.jsx(
22466
+ hasExtendedReactions && /* @__PURE__ */ jsxRuntime.jsx(
22277
22467
  useNotificationApi.Button,
22278
22468
  {
22279
22469
  appearance: "outline",
@@ -26057,7 +26247,7 @@ const UnMemoizedScrollToLatestMessageButton = (props) => {
26057
26247
  /* @__PURE__ */ jsxRuntime.jsx(
26058
26248
  useNotificationApi.Button,
26059
26249
  {
26060
- appearance: "outline",
26250
+ appearance: "ghost",
26061
26251
  "aria-label": t("aria/Jump to latest message"),
26062
26252
  "aria-live": "polite",
26063
26253
  circular: true,
@@ -27103,9 +27293,11 @@ const useConnectionRecoveredListener = (forceUpdate) => {
27103
27293
  const RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS = 5e3;
27104
27294
  const MIN_RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS = 2e3;
27105
27295
  const usePaginatedChannels = (client, filters, sort, options, activeChannelHandler, recoveryThrottleIntervalMs = RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS, customQueryChannels) => {
27296
+ const { addNotification } = useNotificationApi.useNotificationApi();
27106
27297
  const {
27107
27298
  channelsQueryState: { error, setError, setQueryInProgress }
27108
27299
  } = useNotificationApi.useChatContext("usePaginatedChannels");
27300
+ const { t } = useNotificationApi.useTranslationContext();
27109
27301
  const [channels, setChannels] = React.useState([]);
27110
27302
  const [hasNextPage, setHasNextPage] = React.useState(true);
27111
27303
  const lastRecoveryTimestamp = React.useRef(void 0);
@@ -27114,6 +27306,8 @@ const usePaginatedChannels = (client, filters, sort, options, activeChannelHandl
27114
27306
  const sortString = React.useMemo(() => JSON.stringify(sort), [sort]);
27115
27307
  const queryChannels = async (queryType = "load-more") => {
27116
27308
  setError(null);
27309
+ const offset = queryType === "reload" ? 0 : channels.length;
27310
+ const isFirstPage = offset === 0;
27117
27311
  if (queryType === "reload") {
27118
27312
  setChannels([]);
27119
27313
  }
@@ -27127,7 +27321,6 @@ const usePaginatedChannels = (client, filters, sort, options, activeChannelHandl
27127
27321
  setHasNextPage
27128
27322
  });
27129
27323
  } else {
27130
- const offset = queryType === "reload" ? 0 : channels.length;
27131
27324
  const newOptions = {
27132
27325
  offset,
27133
27326
  ...options
@@ -27146,7 +27339,17 @@ const usePaginatedChannels = (client, filters, sort, options, activeChannelHandl
27146
27339
  }
27147
27340
  } catch (error2) {
27148
27341
  console.warn(error2);
27149
- setError(error2);
27342
+ addNotification({
27343
+ emitter: "ChannelList",
27344
+ error: error2 instanceof Error ? error2 : void 0,
27345
+ message: isFirstPage ? t("Failed to load channels") : t("Failed to load more channels"),
27346
+ severity: "error",
27347
+ targetPanels: ["channel-list"],
27348
+ type: isFirstPage ? "api:channel-list:load:failed" : "api:channel-list:load-more:failed"
27349
+ });
27350
+ if (isFirstPage) {
27351
+ setError(error2);
27352
+ }
27150
27353
  }
27151
27354
  setQueryInProgress(null);
27152
27355
  };
@@ -28921,12 +29124,29 @@ const ChannelListItemActionButtons = () => {
28921
29124
  const { t } = useNotificationApi.useTranslationContext();
28922
29125
  const { channel } = useChannelListItemContext();
28923
29126
  const [referenceElement, setReferenceElement] = React.useState(null);
29127
+ const [isRestoringFocus, setIsRestoringFocus] = React.useState(false);
28924
29128
  const dialogId2 = ChannelListItemActionButtons.getDialogId({
28925
29129
  // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
28926
29130
  channelId: channel.id
28927
29131
  });
28928
29132
  const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId2 });
28929
29133
  const dialogIsOpen = useDialogIsOpen(dialogId2, dialogManager?.id);
29134
+ const closeContextMenu = React.useCallback(() => {
29135
+ setIsRestoringFocus(true);
29136
+ dialog?.close();
29137
+ requestAnimationFrame(() => {
29138
+ if (!referenceElement?.isConnected) {
29139
+ setIsRestoringFocus(false);
29140
+ return;
29141
+ }
29142
+ referenceElement.focus();
29143
+ requestAnimationFrame(() => {
29144
+ if (document.activeElement !== referenceElement) {
29145
+ setIsRestoringFocus(false);
29146
+ }
29147
+ });
29148
+ });
29149
+ }, [dialog, referenceElement]);
28930
29150
  const filteredActionSet = useBaseChannelActionSetFilter(defaultChannelActionSet);
28931
29151
  const { dropdownActionSet, quickActionSet, quickDropdownToggleAction } = useSplitActionSet(filteredActionSet);
28932
29152
  if (quickActionSet.length + dropdownActionSet.length === 0) {
@@ -28936,9 +29156,12 @@ const ChannelListItemActionButtons = () => {
28936
29156
  "div",
28937
29157
  {
28938
29158
  className: clsx("str-chat__channel-list-item__action-buttons", {
28939
- "str-chat__channel-list-item__action-buttons--active": dialogIsOpen
29159
+ "str-chat__channel-list-item__action-buttons--active": dialogIsOpen || isRestoringFocus
28940
29160
  }),
28941
29161
  "data-testid": "channel-list-item-action-buttons",
29162
+ onFocusCapture: () => {
29163
+ setIsRestoringFocus(false);
29164
+ },
28942
29165
  children: [
28943
29166
  quickDropdownToggleAction && dropdownActionSet.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(quickDropdownToggleAction.Component, { ref: setReferenceElement }),
28944
29167
  quickActionSet.map(({ Component, type }) => /* @__PURE__ */ jsxRuntime.jsx(Component, {}, type)),
@@ -28950,7 +29173,7 @@ const ChannelListItemActionButtons = () => {
28950
29173
  "data-testid": "channel-list-item-context-menu",
28951
29174
  dialogManagerId: dialogManager?.id,
28952
29175
  id: dialog.id,
28953
- onClose: dialog?.close,
29176
+ onClose: closeContextMenu,
28954
29177
  placement: "bottom-start",
28955
29178
  referenceElement,
28956
29179
  tabIndex: -1,
@@ -29192,6 +29415,7 @@ const UnMemoizedChannelListItemUI = (props) => {
29192
29415
  messageDeliveryStatus,
29193
29416
  muted,
29194
29417
  onSelect: customOnSelectChannel,
29418
+ pinned,
29195
29419
  setActiveChannel,
29196
29420
  unread,
29197
29421
  watchers
@@ -29214,7 +29438,6 @@ const UnMemoizedChannelListItemUI = (props) => {
29214
29438
  }
29215
29439
  };
29216
29440
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__channel-list-item-container", children: [
29217
- /* @__PURE__ */ jsxRuntime.jsx(ChannelListItemActionButtons$1, {}),
29218
29441
  /* @__PURE__ */ jsxRuntime.jsxs(
29219
29442
  "button",
29220
29443
  {
@@ -29224,8 +29447,11 @@ const UnMemoizedChannelListItemUI = (props) => {
29224
29447
  "aria-selected": active,
29225
29448
  className: clsx(
29226
29449
  "str-chat__channel-list-item",
29227
- typeof unread === "number" && unread > 0 && "str-chat__channel-list-item--unread",
29228
- muted && "str-chat__channel-list-item--muted",
29450
+ {
29451
+ "str-chat__channel-list-item--muted": muted,
29452
+ "str-chat__channel-list-item--pinned": pinned,
29453
+ "str-chat__channel-list-item--unread": typeof unread === "number" && unread > 0
29454
+ },
29229
29455
  customClassName
29230
29456
  ),
29231
29457
  "data-testid": "channel-list-item-button",
@@ -29246,6 +29472,7 @@ const UnMemoizedChannelListItemUI = (props) => {
29246
29472
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__channel-list-item-data__first-row", children: [
29247
29473
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__channel-list-item-data__title", children: [
29248
29474
  /* @__PURE__ */ jsxRuntime.jsx("span", { children: displayTitle || "N/A" }),
29475
+ pinned && /* @__PURE__ */ jsxRuntime.jsx(useNotificationApi.IconPin, {}),
29249
29476
  muted && /* @__PURE__ */ jsxRuntime.jsx(useNotificationApi.IconMute, {})
29250
29477
  ] }),
29251
29478
  /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "str-chat__channel-list-item-data__timestamp-and-badge", children: [
@@ -29264,7 +29491,8 @@ const UnMemoizedChannelListItemUI = (props) => {
29264
29491
  ] })
29265
29492
  ]
29266
29493
  }
29267
- )
29494
+ ),
29495
+ /* @__PURE__ */ jsxRuntime.jsx(ChannelListItemActionButtons$1, {})
29268
29496
  ] });
29269
29497
  };
29270
29498
  const ChannelListItemUI = React.memo(
@@ -29367,6 +29595,7 @@ const ChannelListItem = (props) => {
29367
29595
  const { displayImage, displayTitle, groupChannelDisplayInfo } = useChannelPreviewInfo({
29368
29596
  channel
29369
29597
  });
29598
+ const membership = useChannelMembershipState(channel);
29370
29599
  const [lastMessage, setLastMessage] = React.useState(
29371
29600
  channel.state.messages[channel.state.messages.length - 1]
29372
29601
  );
@@ -29463,6 +29692,7 @@ const ChannelListItem = (props) => {
29463
29692
  latestMessagePreview,
29464
29693
  messageDeliveryStatus,
29465
29694
  muted,
29695
+ pinned: !!membership.pinned_at,
29466
29696
  setActiveChannel,
29467
29697
  unread
29468
29698
  }
@@ -30417,7 +30647,7 @@ const useChat = ({
30417
30647
  };
30418
30648
  React.useEffect(() => {
30419
30649
  if (!client) return;
30420
- const version = "14.1.0";
30650
+ const version = "14.2.0";
30421
30651
  const userAgent = client.getUserAgent();
30422
30652
  if (!userAgent.includes("stream-chat-react")) {
30423
30653
  client.setUserAgent(`stream-chat-react-${version}-${userAgent}`);
@@ -31166,6 +31396,7 @@ exports.renderPreviewText = renderPreviewText;
31166
31396
  exports.renderText = renderText;
31167
31397
  exports.resampleWaveformData = resampleWaveformData;
31168
31398
  exports.ruTranslations = ruTranslations;
31399
+ exports.shouldBackspaceExitCommandMode = shouldBackspaceExitCommandMode;
31169
31400
  exports.shouldConsiderArchivedChannels = shouldConsiderArchivedChannels;
31170
31401
  exports.shouldConsiderPinnedChannels = shouldConsiderPinnedChannels;
31171
31402
  exports.toBaseImageDescriptors = toBaseImageDescriptors;
@@ -31208,6 +31439,7 @@ exports.useMarkUnreadHandler = useMarkUnreadHandler;
31208
31439
  exports.useMentionsHandler = useMentionsHandler;
31209
31440
  exports.useMessageBounceContext = useMessageBounceContext;
31210
31441
  exports.useMessageComposerBindings = useMessageComposerBindings;
31442
+ exports.useMessageComposerCommands = useMessageComposerCommands;
31211
31443
  exports.useMessageComposerHasSendableData = useMessageComposerHasSendableData;
31212
31444
  exports.useMessageContentIsEmpty = useMessageContentIsEmpty;
31213
31445
  exports.useMessageContext = useMessageContext;