stream-chat-react 14.1.0 → 14.3.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.
- package/README.md +7 -9
- package/dist/cjs/emojis.js +1 -1
- package/dist/cjs/index.js +499 -82
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{useNotificationApi.fd802923.js → useNotificationApi.f2c7704d.js} +4 -4
- package/dist/cjs/{useNotificationApi.fd802923.js.map → useNotificationApi.f2c7704d.js.map} +1 -1
- package/dist/css/index.css +167 -72
- package/dist/css/index.css.map +1 -1
- package/dist/es/emojis.mjs +1 -1
- package/dist/es/index.mjs +500 -83
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/{useNotificationApi.e0c52de6.mjs → useNotificationApi.f91ae46b.mjs} +4 -4
- package/dist/es/{useNotificationApi.e0c52de6.mjs.map → useNotificationApi.f91ae46b.mjs.map} +1 -1
- package/dist/types/components/BaseImage/BaseImage.d.ts.map +1 -1
- package/dist/types/components/ChannelList/ChannelList.d.ts.map +1 -1
- package/dist/types/components/ChannelList/hooks/usePaginatedChannels.d.ts +12 -1
- package/dist/types/components/ChannelList/hooks/usePaginatedChannels.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/ChannelListItem.d.ts +2 -0
- package/dist/types/components/ChannelListItem/ChannelListItem.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/ChannelListItemActionButtons.d.ts.map +1 -1
- package/dist/types/components/ChannelListItem/ChannelListItemUI.d.ts.map +1 -1
- package/dist/types/components/Form/Dropdown.d.ts +2 -1
- package/dist/types/components/Form/Dropdown.d.ts.map +1 -1
- package/dist/types/components/Message/MessageText.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/AttachmentSelector/AttachmentSelector.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/AttachmentSelector/CommandsMenu.d.ts +2 -1
- package/dist/types/components/MessageComposer/AttachmentSelector/CommandsMenu.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/EditedMessagePreview.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/QuotedMessagePreview.d.ts +4 -2
- package/dist/types/components/MessageComposer/QuotedMessagePreview.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/WithDragAndDropUpload.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/hooks/index.d.ts +1 -0
- package/dist/types/components/MessageComposer/hooks/index.d.ts.map +1 -1
- package/dist/types/components/MessageComposer/hooks/useMessageComposerCommands.d.ts +9 -0
- package/dist/types/components/MessageComposer/hooks/useMessageComposerCommands.d.ts.map +1 -0
- package/dist/types/components/Notifications/NotificationList.d.ts +58 -1
- package/dist/types/components/Notifications/NotificationList.d.ts.map +1 -1
- package/dist/types/components/Reactions/MessageReactionsDetail.d.ts.map +1 -1
- package/dist/types/components/Reactions/ReactionSelector.d.ts.map +1 -1
- package/dist/types/components/Reactions/reactionOptions.d.ts +1 -0
- package/dist/types/components/Reactions/reactionOptions.d.ts.map +1 -1
- package/dist/types/components/TextareaComposer/SuggestionList/CommandItem.d.ts +1 -0
- package/dist/types/components/TextareaComposer/SuggestionList/CommandItem.d.ts.map +1 -1
- package/dist/types/components/TextareaComposer/SuggestionList/SuggestionList.d.ts.map +1 -1
- package/dist/types/components/TextareaComposer/TextareaComposer.d.ts +1 -0
- package/dist/types/components/TextareaComposer/TextareaComposer.d.ts.map +1 -1
- package/dist/types/i18n/Streami18n.d.ts +6 -0
- package/dist/types/i18n/Streami18n.d.ts.map +1 -1
- package/dist/types/i18n/TranslationBuilder/notifications/translators.d.ts +1 -0
- package/dist/types/i18n/TranslationBuilder/notifications/translators.d.ts.map +1 -1
- package/dist/types/i18n/TranslationBuilder/notifications/translatorsByNotificationType.d.ts.map +1 -1
- package/package.json +9 -5
package/dist/es/index.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import clsx from "clsx";
|
|
|
3
3
|
import { nanoid } from "nanoid";
|
|
4
4
|
import React, { useState, useEffect, useContext, createContext, useCallback, useLayoutEffect, useMemo, useRef, forwardRef, createElement, Component, useId, isValidElement, Fragment as Fragment$1, useSyncExternalStore } from "react";
|
|
5
5
|
import { u as useHandleFileChangeWrapper, d as dataTransferItemsToFiles, r as renderAudio, t as toAudioBuffer, c as createFileFromBlobs, g as getExtensionFromMimeType, a as getRecordedMediaTypeFromMimeType } from "./audioProcessing.21cb49e1.mjs";
|
|
6
|
-
import { u as useStateStore, a as useMessageComposerController, i as isMessageBounced, b as useChannelActionContext, C as ComponentContext, c as useTranslationContext, d as useChannelStateContext, e as useChatContext, f as isNotificationForPanel, B as Button, I as IconPauseFill, g as IconPlayFill, h as getDefaultExportFromCjs, j as defaultTranslatorFunction, p as predefinedFormatters, L as LocalizedFormat, k as calendar, l as IconLoading, m as useComponentContext, n as isNetworkSendFailure, o as isUserMuted, q as useThreadContext, r as usePopoverPosition, s as IconXmark, t as IconUser, v as IconExclamationMarkFill, w as IconChevronRight, x as IconChevronLeft, y as IconArrowLeft, z as IconExclamationMark, A as IconNoSign, D as isMessageDeleted, E as isMessageErrorRetryable, F as ACTIONS_NOT_WORKING_IN_THREAD, G as useNotificationApi, H as IconArrowUpRight, J as IconPin, K as mapToUserNameOrId, M as IconClock, N as IconCheckmark1Small, O as IconChecks, P as getReadByTooltipText, Q as messageHasAttachments, R as messageTextHasEmojisOnly, S as isDate, T as getDateString, U as IconTranslate, V as IconDownload, W as useAudioPlayer, X as IconImage, Y as IconArrowDownCircle, Z as IconRetry, _ as IconLink, $ as IconGiphy, a0 as IconLocation, a1 as IconUnsupportedAttachment, a2 as IconEyeFill, a3 as useMessageComposerContext, a4 as useIsCooldownActive, a5 as IconXmarkSmall, a6 as IconPoll, a7 as IconFile, a8 as IconVideo, a9 as IconCamera, aa as IconVoice, ab as IconBookmark, ac as IconBell, ad as IconChevronDown, ae as IconMinus, af as IconPlusSmall, ag as IconCheckmark, ah as DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD, ai as IconTrophy, aj as IconReorder, ak as IconMinusCircle, al as IconSend, am as IconAudio, an as IconUserAdd, ao as IconMute, ap as IconFlag, aq as IconUserRemove, ar as IconAttachment, as as IconCommand, at as CHANNEL_CONTAINER_ID, au as IconPlus, av as IconExclamationTriangleFill, aw as IconMicrophoneSolid, ax as IconVideoFill, ay as IconBolt, az as IconDelete, aA as IconUpload, aB as MessageComposerContextProvider, aC as useTypingContext, aD as useChatViewContext, aE as MESSAGE_ACTIONS, aF as LegacyThreadContext, aG as IconEmojiAdd, aH as IconReply, aI as IconEmoji, aJ as IconMore, aK as IconUserCheck, aL as IconBookmarkRemove, aM as IconBellOff, aN as IconNotification, aO as IconEdit, aP as IconCopy, aQ as IconUnpin, aR as IconQuote, aS as IconThread, aT as areMessageUIPropsEqual, aU as isDateSeparatorMessage, aV as isMessageBlocked, aW as messageHasSingleAttachment, aX as messageHasGiphyAttachment, aY as messageHasReactions, aZ as messageHasQuotedMessage, a_ as isMessageEdited, a$ as countEmojis, b0 as areMessagePropsEqual, b1 as getMessageActions, b2 as processMessages, b3 as insertIntro, b4 as getGroupStyles, b5 as getLastReceived, b6 as IconArrowUp, b7 as isIntroMessage, b8 as isLocalMessage, b9 as getIsFirstUnreadMessage, ba as IconArrowDown, bb as DEFAULT_NEXT_CHANNEL_PAGE_SIZE, bc as EmptyStateIndicator, bd as useNotificationTarget, be as getChannel, bf as IconSearch, bg as IconXCircle, bh as useChannelListContext, bi as DEFAULT_JUMP_TO_PAGE_SIZE, bj as ChannelListContextProvider, bk as IconLeave, bl as IconArchive, bm as IconExclamationCircleFill, bn as useThreadsViewContext, bo as IconMessageBubbles, bp as IconRefresh, bq as hasSystemNotificationTag, br as defaultDateTimeParser, bs as isLanguageSupported, bt as ChatProvider, bu as TranslationProvider } from "./useNotificationApi.
|
|
7
|
-
import { bz, bC, c4, c5, c6, c7, c8, c9, bE, bH, bD, bG, bI, ca, bL, bM, bN, bO, bP, cb, bR, bX, c2, c3, cc, cd, ce, bw, c0, bK, bJ, bx, by, bS, bT, bZ, b_, b$, bW, cf, bY, cg, bV, bU, bv, bF, bA, bB, c1, bQ } from "./useNotificationApi.
|
|
6
|
+
import { u as useStateStore, a as useMessageComposerController, i as isMessageBounced, b as useChannelActionContext, C as ComponentContext, c as useTranslationContext, d as useChannelStateContext, e as useChatContext, f as isNotificationForPanel, B as Button, I as IconPauseFill, g as IconPlayFill, h as getDefaultExportFromCjs, j as defaultTranslatorFunction, p as predefinedFormatters, L as LocalizedFormat, k as calendar, l as IconLoading, m as useComponentContext, n as isNetworkSendFailure, o as isUserMuted, q as useThreadContext, r as usePopoverPosition, s as IconXmark, t as IconUser, v as IconExclamationMarkFill, w as IconChevronRight, x as IconChevronLeft, y as IconArrowLeft, z as IconExclamationMark, A as IconNoSign, D as isMessageDeleted, E as isMessageErrorRetryable, F as ACTIONS_NOT_WORKING_IN_THREAD, G as useNotificationApi, H as IconArrowUpRight, J as IconPin, K as mapToUserNameOrId, M as IconClock, N as IconCheckmark1Small, O as IconChecks, P as getReadByTooltipText, Q as messageHasAttachments, R as messageTextHasEmojisOnly, S as isDate, T as getDateString, U as IconTranslate, V as IconDownload, W as useAudioPlayer, X as IconImage, Y as IconArrowDownCircle, Z as IconRetry, _ as IconLink, $ as IconGiphy, a0 as IconLocation, a1 as IconUnsupportedAttachment, a2 as IconEyeFill, a3 as useMessageComposerContext, a4 as useIsCooldownActive, a5 as IconXmarkSmall, a6 as IconPoll, a7 as IconFile, a8 as IconVideo, a9 as IconCamera, aa as IconVoice, ab as IconBookmark, ac as IconBell, ad as IconChevronDown, ae as IconMinus, af as IconPlusSmall, ag as IconCheckmark, ah as DEFAULT_LOAD_PAGE_SCROLL_THRESHOLD, ai as IconTrophy, aj as IconReorder, ak as IconMinusCircle, al as IconSend, am as IconAudio, an as IconUserAdd, ao as IconMute, ap as IconFlag, aq as IconUserRemove, ar as IconAttachment, as as IconCommand, at as CHANNEL_CONTAINER_ID, au as IconPlus, av as IconExclamationTriangleFill, aw as IconMicrophoneSolid, ax as IconVideoFill, ay as IconBolt, az as IconDelete, aA as IconUpload, aB as MessageComposerContextProvider, aC as useTypingContext, aD as useChatViewContext, aE as MESSAGE_ACTIONS, aF as LegacyThreadContext, aG as IconEmojiAdd, aH as IconReply, aI as IconEmoji, aJ as IconMore, aK as IconUserCheck, aL as IconBookmarkRemove, aM as IconBellOff, aN as IconNotification, aO as IconEdit, aP as IconCopy, aQ as IconUnpin, aR as IconQuote, aS as IconThread, aT as areMessageUIPropsEqual, aU as isDateSeparatorMessage, aV as isMessageBlocked, aW as messageHasSingleAttachment, aX as messageHasGiphyAttachment, aY as messageHasReactions, aZ as messageHasQuotedMessage, a_ as isMessageEdited, a$ as countEmojis, b0 as areMessagePropsEqual, b1 as getMessageActions, b2 as processMessages, b3 as insertIntro, b4 as getGroupStyles, b5 as getLastReceived, b6 as IconArrowUp, b7 as isIntroMessage, b8 as isLocalMessage, b9 as getIsFirstUnreadMessage, ba as IconArrowDown, bb as DEFAULT_NEXT_CHANNEL_PAGE_SIZE, bc as EmptyStateIndicator, bd as useNotificationTarget, be as getChannel, bf as IconSearch, bg as IconXCircle, bh as useChannelListContext, bi as DEFAULT_JUMP_TO_PAGE_SIZE, bj as ChannelListContextProvider, bk as IconLeave, bl as IconArchive, bm as IconExclamationCircleFill, bn as useThreadsViewContext, bo as IconMessageBubbles, bp as IconRefresh, bq as hasSystemNotificationTag, br as defaultDateTimeParser, bs as isLanguageSupported, bt as ChatProvider, bu as TranslationProvider } from "./useNotificationApi.f91ae46b.mjs";
|
|
7
|
+
import { bz, bC, c4, c5, c6, c7, c8, c9, bE, bH, bD, bG, bI, ca, bL, bM, bN, bO, bP, cb, bR, bX, c2, c3, cc, cd, ce, bw, c0, bK, bJ, bx, by, bS, bT, bZ, b_, b$, bW, cf, bY, cg, bV, bU, bv, bF, bA, bB, c1, bQ } from "./useNotificationApi.f91ae46b.mjs";
|
|
8
8
|
import { createPortal } from "react-dom";
|
|
9
9
|
import { StateStore, isFileAttachment, isImageAttachment, isVideoAttachment, isAudioAttachment, isVoiceRecordingAttachment, formatMessage, isGiphyAttachment, isScrapedContent, isLocalVideoAttachment, isLocalImageAttachment, isSharedLocationResponse, LiveLocationManager, MessageComposer as MessageComposer$1, isVoteAnswer, VotingVisibility, isLocalVoiceRecordingAttachment, isLocalAudioAttachment, isLocalFileAttachment, isLocalAttachment, LinkPreviewsManager, SearchController, ChannelSearchSource, UserSearchSource, MessageSearchSource, StreamChat } from "stream-chat";
|
|
10
10
|
import { sanitizeUrl } from "@braintree/sanitize-url";
|
|
@@ -964,7 +964,9 @@ const deTranslations = {
|
|
|
964
964
|
"aria/Mark messages as read": "Nachrichten als gelesen markieren",
|
|
965
965
|
"aria/Menu": "Menü",
|
|
966
966
|
"aria/Message Actions": "Nachrichtenaktionen",
|
|
967
|
+
"aria/Message from {{ user }},": "Nachricht von {{ user }},",
|
|
967
968
|
"aria/Message Options": "Nachrichtenoptionen",
|
|
969
|
+
"aria/Message,": "Nachricht,",
|
|
968
970
|
"aria/Mute User": "Benutzer stummschalten",
|
|
969
971
|
"aria/Notifications": "Benachrichtigungen",
|
|
970
972
|
"aria/Open Attachment Selector": "Anhang-Auswahl öffnen",
|
|
@@ -1033,6 +1035,8 @@ const deTranslations = {
|
|
|
1033
1035
|
"Close dialog": "Dialog schließen",
|
|
1034
1036
|
"Close emoji picker": "Emoji-Auswahl schließen",
|
|
1035
1037
|
"Close prompt: {{ title }}": "Eingabeaufforderung schließen: {{ title }}",
|
|
1038
|
+
"Command not available while editing": "Befehl beim Bearbeiten nicht verfügbar",
|
|
1039
|
+
"Command not available while replying": "Befehl beim Antworten nicht verfügbar",
|
|
1036
1040
|
Commands: Commands$b,
|
|
1037
1041
|
"Commands matching": "Übereinstimmende Befehle",
|
|
1038
1042
|
"Connection failure, reconnecting now...": "Verbindungsfehler, Wiederherstellung der Verbindung...",
|
|
@@ -1092,6 +1096,8 @@ const deTranslations = {
|
|
|
1092
1096
|
"Failed to end the poll due to {{reason}}": "Umfrage konnte aufgrund von {{reason}} nicht beendet werden",
|
|
1093
1097
|
"Failed to jump to the first unread message": "Fehler beim Springen zur ersten ungelesenen Nachricht",
|
|
1094
1098
|
"Failed to leave channel": "Kanal konnte nicht verlassen werden",
|
|
1099
|
+
"Failed to load channels": "Kanäle konnten nicht geladen werden",
|
|
1100
|
+
"Failed to load more channels": "Weitere Kanäle konnten nicht geladen werden",
|
|
1095
1101
|
"Failed to mark channel as read": "Fehler beim Markieren des Kanals als gelesen",
|
|
1096
1102
|
"Failed to play the recording": "Wiedergabe der Aufnahme fehlgeschlagen",
|
|
1097
1103
|
"Failed to retrieve location": "Standort konnte nicht abgerufen werden",
|
|
@@ -1554,7 +1560,9 @@ const enTranslations = {
|
|
|
1554
1560
|
"aria/Mark messages as read": "Mark messages as read",
|
|
1555
1561
|
"aria/Menu": "Menu",
|
|
1556
1562
|
"aria/Message Actions": "Message Actions",
|
|
1563
|
+
"aria/Message from {{ user }},": "Message from {{ user }},",
|
|
1557
1564
|
"aria/Message Options": "Message Options",
|
|
1565
|
+
"aria/Message,": "Message,",
|
|
1558
1566
|
"aria/Mute User": "Mute User",
|
|
1559
1567
|
"aria/Notifications": "Notifications",
|
|
1560
1568
|
"aria/Open Attachment Selector": "Open Attachment Selector",
|
|
@@ -1623,6 +1631,8 @@ const enTranslations = {
|
|
|
1623
1631
|
"Close dialog": "Close dialog",
|
|
1624
1632
|
"Close emoji picker": "Close emoji picker",
|
|
1625
1633
|
"Close prompt: {{ title }}": "Close prompt: {{ title }}",
|
|
1634
|
+
"Command not available while editing": "Command not available while editing",
|
|
1635
|
+
"Command not available while replying": "Command not available while replying",
|
|
1626
1636
|
Commands: Commands$a,
|
|
1627
1637
|
"Commands matching": "Commands matching",
|
|
1628
1638
|
"Connection failure, reconnecting now...": "Connection failure, reconnecting now...",
|
|
@@ -1682,6 +1692,8 @@ const enTranslations = {
|
|
|
1682
1692
|
"Failed to end the poll due to {{reason}}": "Failed to end the poll due to {{reason}}",
|
|
1683
1693
|
"Failed to jump to the first unread message": "Failed to jump to the first unread message",
|
|
1684
1694
|
"Failed to leave channel": "Failed to leave channel",
|
|
1695
|
+
"Failed to load channels": "Failed to load channels",
|
|
1696
|
+
"Failed to load more channels": "Failed to load more channels",
|
|
1685
1697
|
"Failed to mark channel as read": "Failed to mark channel as read",
|
|
1686
1698
|
"Failed to play the recording": "Failed to play the recording",
|
|
1687
1699
|
"Failed to retrieve location": "Failed to retrieve location",
|
|
@@ -2160,7 +2172,9 @@ const esTranslations = {
|
|
|
2160
2172
|
"aria/Mark messages as read": "Marcar mensajes como leídos",
|
|
2161
2173
|
"aria/Menu": "Menú",
|
|
2162
2174
|
"aria/Message Actions": "Acciones del mensaje",
|
|
2175
|
+
"aria/Message from {{ user }},": "Mensaje de {{ user }},",
|
|
2163
2176
|
"aria/Message Options": "Opciones de mensaje",
|
|
2177
|
+
"aria/Message,": "Mensaje,",
|
|
2164
2178
|
"aria/Mute User": "Silenciar usuario",
|
|
2165
2179
|
"aria/Notifications": "Notificaciones",
|
|
2166
2180
|
"aria/Open Attachment Selector": "Abrir selector de adjuntos",
|
|
@@ -2229,6 +2243,8 @@ const esTranslations = {
|
|
|
2229
2243
|
"Close dialog": "Cerrar diálogo",
|
|
2230
2244
|
"Close emoji picker": "Cerrar el selector de emojis",
|
|
2231
2245
|
"Close prompt: {{ title }}": "Cerrar diálogo: {{ title }}",
|
|
2246
|
+
"Command not available while editing": "Comando no disponible durante la edición",
|
|
2247
|
+
"Command not available while replying": "Comando no disponible mientras se responde",
|
|
2232
2248
|
Commands: Commands$9,
|
|
2233
2249
|
"Commands matching": "Coincidencia de comandos",
|
|
2234
2250
|
"Connection failure, reconnecting now...": "Fallo de conexión, reconectando ahora...",
|
|
@@ -2288,6 +2304,8 @@ const esTranslations = {
|
|
|
2288
2304
|
"Failed to end the poll due to {{reason}}": "No se pudo terminar la encuesta debido a {{reason}}",
|
|
2289
2305
|
"Failed to jump to the first unread message": "Error al saltar al primer mensaje no leído",
|
|
2290
2306
|
"Failed to leave channel": "No se pudo salir del canal",
|
|
2307
|
+
"Failed to load channels": "No se pudieron cargar los canales",
|
|
2308
|
+
"Failed to load more channels": "No se pudieron cargar más canales",
|
|
2291
2309
|
"Failed to mark channel as read": "Error al marcar el canal como leído",
|
|
2292
2310
|
"Failed to play the recording": "No se pudo reproducir la grabación",
|
|
2293
2311
|
"Failed to retrieve location": "No se pudo obtener la ubicación",
|
|
@@ -2777,7 +2795,9 @@ const frTranslations = {
|
|
|
2777
2795
|
"aria/Mark messages as read": "Marquer les messages comme lus",
|
|
2778
2796
|
"aria/Menu": "Menu",
|
|
2779
2797
|
"aria/Message Actions": "Actions du message",
|
|
2798
|
+
"aria/Message from {{ user }},": "Message de {{ user }},",
|
|
2780
2799
|
"aria/Message Options": "Options du message",
|
|
2800
|
+
"aria/Message,": "Message,",
|
|
2781
2801
|
"aria/Mute User": "Mettre en sourdine",
|
|
2782
2802
|
"aria/Notifications": "Notifications",
|
|
2783
2803
|
"aria/Open Attachment Selector": "Ouvrir le sélecteur de pièces jointes",
|
|
@@ -2846,6 +2866,8 @@ const frTranslations = {
|
|
|
2846
2866
|
"Close dialog": "Fermer la boîte de dialogue",
|
|
2847
2867
|
"Close emoji picker": "Fermer le sélecteur d'émojis",
|
|
2848
2868
|
"Close prompt: {{ title }}": "Fermer l'invite : {{ title }}",
|
|
2869
|
+
"Command not available while editing": "Commande non disponible pendant la modification",
|
|
2870
|
+
"Command not available while replying": "Commande non disponible pendant la réponse",
|
|
2849
2871
|
Commands: Commands$8,
|
|
2850
2872
|
"Commands matching": "Correspondance des commandes",
|
|
2851
2873
|
"Connection failure, reconnecting now...": "Échec de la connexion, reconnexion en cours...",
|
|
@@ -2905,6 +2927,8 @@ const frTranslations = {
|
|
|
2905
2927
|
"Failed to end the poll due to {{reason}}": "Impossible de terminer le sondage en raison de {{reason}}",
|
|
2906
2928
|
"Failed to jump to the first unread message": "Échec du saut vers le premier message non lu",
|
|
2907
2929
|
"Failed to leave channel": "Impossible de quitter le canal",
|
|
2930
|
+
"Failed to load channels": "Impossible de charger les canaux",
|
|
2931
|
+
"Failed to load more channels": "Impossible de charger davantage de canaux",
|
|
2908
2932
|
"Failed to mark channel as read": "Échec du marquage du canal comme lu",
|
|
2909
2933
|
"Failed to play the recording": "Impossible de lire l'enregistrement",
|
|
2910
2934
|
"Failed to retrieve location": "Impossible de récupérer l'emplacement",
|
|
@@ -3378,7 +3402,9 @@ const hiTranslations = {
|
|
|
3378
3402
|
"aria/Mark messages as read": "संदेशों को पढ़ा हुआ चिह्नित करें",
|
|
3379
3403
|
"aria/Menu": "मेन्यू",
|
|
3380
3404
|
"aria/Message Actions": "संदेश कार्रवाइयाँ",
|
|
3405
|
+
"aria/Message from {{ user }},": "{{ user }} का संदेश,",
|
|
3381
3406
|
"aria/Message Options": "संदेश विकल्प",
|
|
3407
|
+
"aria/Message,": "संदेश,",
|
|
3382
3408
|
"aria/Mute User": "उपयोगकर्ता म्यूट करें",
|
|
3383
3409
|
"aria/Notifications": "सूचनाएं",
|
|
3384
3410
|
"aria/Open Attachment Selector": "अटैचमेंट चयनकर्ता खोलें",
|
|
@@ -3447,6 +3473,8 @@ const hiTranslations = {
|
|
|
3447
3473
|
"Close dialog": "डायलॉग बंद करें",
|
|
3448
3474
|
"Close emoji picker": "इमोजी पिकर बंद करें",
|
|
3449
3475
|
"Close prompt: {{ title }}": "प्रॉम्प्ट बंद करें: {{ title }}",
|
|
3476
|
+
"Command not available while editing": "संपादन के दौरान कमांड उपलब्ध नहीं है",
|
|
3477
|
+
"Command not available while replying": "उत्तर देते समय कमांड उपलब्ध नहीं है",
|
|
3450
3478
|
Commands: Commands$7,
|
|
3451
3479
|
"Commands matching": "मेल खाती है",
|
|
3452
3480
|
"Connection failure, reconnecting now...": "कनेक्शन विफल रहा, अब पुनः कनेक्ट हो रहा है ...",
|
|
@@ -3507,6 +3535,8 @@ const hiTranslations = {
|
|
|
3507
3535
|
"Failed to end the poll due to {{reason}}": "{{reason}} के कारण पोल समाप्त करने में विफल",
|
|
3508
3536
|
"Failed to jump to the first unread message": "पहले अपठित संदेश पर जाने में विफल",
|
|
3509
3537
|
"Failed to leave channel": "चैनल छोड़ने में विफल",
|
|
3538
|
+
"Failed to load channels": "चैनल लोड करने में विफल",
|
|
3539
|
+
"Failed to load more channels": "और चैनल लोड करने में विफल",
|
|
3510
3540
|
"Failed to mark channel as read": "चैनल को पढ़ा हुआ चिह्नित करने में विफल।",
|
|
3511
3541
|
"Failed to play the recording": "रेकॉर्डिंग प्ले करने में विफल",
|
|
3512
3542
|
"Failed to retrieve location": "स्थान प्राप्त करने में विफल",
|
|
@@ -3985,7 +4015,9 @@ const itTranslations = {
|
|
|
3985
4015
|
"aria/Mark messages as read": "Segna i messaggi come letti",
|
|
3986
4016
|
"aria/Menu": "Menu",
|
|
3987
4017
|
"aria/Message Actions": "Azioni del messaggio",
|
|
4018
|
+
"aria/Message from {{ user }},": "Messaggio di {{ user }},",
|
|
3988
4019
|
"aria/Message Options": "Opzioni di messaggio",
|
|
4020
|
+
"aria/Message,": "Messaggio,",
|
|
3989
4021
|
"aria/Mute User": "Mute utente",
|
|
3990
4022
|
"aria/Notifications": "Notifiche",
|
|
3991
4023
|
"aria/Open Attachment Selector": "Apri selettore allegati",
|
|
@@ -4054,6 +4086,8 @@ const itTranslations = {
|
|
|
4054
4086
|
"Close dialog": "Chiudi finestra di dialogo",
|
|
4055
4087
|
"Close emoji picker": "Chiudi il selettore di emoji",
|
|
4056
4088
|
"Close prompt: {{ title }}": "Chiudi prompt: {{ title }}",
|
|
4089
|
+
"Command not available while editing": "Comando non disponibile durante la modifica",
|
|
4090
|
+
"Command not available while replying": "Comando non disponibile durante la risposta",
|
|
4057
4091
|
Commands: Commands$6,
|
|
4058
4092
|
"Commands matching": "Comandi corrispondenti",
|
|
4059
4093
|
"Connection failure, reconnecting now...": "Errore di connessione, riconnessione in corso...",
|
|
@@ -4113,6 +4147,8 @@ const itTranslations = {
|
|
|
4113
4147
|
"Failed to end the poll due to {{reason}}": "Impossibile terminare il sondaggio a causa di {{reason}}",
|
|
4114
4148
|
"Failed to jump to the first unread message": "Impossibile passare al primo messaggio non letto",
|
|
4115
4149
|
"Failed to leave channel": "Impossibile lasciare il canale",
|
|
4150
|
+
"Failed to load channels": "Impossibile caricare i canali",
|
|
4151
|
+
"Failed to load more channels": "Impossibile caricare altri canali",
|
|
4116
4152
|
"Failed to mark channel as read": "Impossibile contrassegnare il canale come letto",
|
|
4117
4153
|
"Failed to play the recording": "Impossibile riprodurre la registrazione",
|
|
4118
4154
|
"Failed to retrieve location": "Impossibile recuperare la posizione",
|
|
@@ -4579,7 +4615,9 @@ const jaTranslations = {
|
|
|
4579
4615
|
"aria/Mark messages as read": "メッセージを既読にする",
|
|
4580
4616
|
"aria/Menu": "メニュー",
|
|
4581
4617
|
"aria/Message Actions": "メッセージ操作",
|
|
4618
|
+
"aria/Message from {{ user }},": "{{ user }}さんからのメッセージ,",
|
|
4582
4619
|
"aria/Message Options": "メッセージオプション",
|
|
4620
|
+
"aria/Message,": "メッセージ,",
|
|
4583
4621
|
"aria/Mute User": "ユーザーをミュート",
|
|
4584
4622
|
"aria/Notifications": "通知",
|
|
4585
4623
|
"aria/Open Attachment Selector": "添付ファイル選択を開く",
|
|
@@ -4648,6 +4686,8 @@ const jaTranslations = {
|
|
|
4648
4686
|
"Close dialog": "ダイアログを閉じる",
|
|
4649
4687
|
"Close emoji picker": "絵文字ピッカーを閉める",
|
|
4650
4688
|
"Close prompt: {{ title }}": "プロンプトを閉じる: {{ title }}",
|
|
4689
|
+
"Command not available while editing": "編集中はコマンドを使用できません",
|
|
4690
|
+
"Command not available while replying": "返信中はコマンドを使用できません",
|
|
4651
4691
|
Commands: Commands$5,
|
|
4652
4692
|
"Commands matching": "一致するコマンド",
|
|
4653
4693
|
"Connection failure, reconnecting now...": "接続が失敗しました。再接続中...",
|
|
@@ -4707,6 +4747,8 @@ const jaTranslations = {
|
|
|
4707
4747
|
"Failed to end the poll due to {{reason}}": "{{reason}}のためアンケートの終了に失敗しました",
|
|
4708
4748
|
"Failed to jump to the first unread message": "最初の未読メッセージにジャンプできませんでした",
|
|
4709
4749
|
"Failed to leave channel": "チャンネルの退出に失敗しました",
|
|
4750
|
+
"Failed to load channels": "チャンネルの読み込みに失敗しました",
|
|
4751
|
+
"Failed to load more channels": "さらにチャンネルを読み込めませんでした",
|
|
4710
4752
|
"Failed to mark channel as read": "チャンネルを既読にすることができませんでした",
|
|
4711
4753
|
"Failed to play the recording": "録音の再生に失敗しました",
|
|
4712
4754
|
"Failed to retrieve location": "位置情報の取得に失敗しました",
|
|
@@ -5155,7 +5197,9 @@ const koTranslations = {
|
|
|
5155
5197
|
"aria/Mark messages as read": "메시지를 읽음으로 표시",
|
|
5156
5198
|
"aria/Menu": "메뉴",
|
|
5157
5199
|
"aria/Message Actions": "메시지 작업",
|
|
5200
|
+
"aria/Message from {{ user }},": "{{ user }}의 메시지,",
|
|
5158
5201
|
"aria/Message Options": "메시지 옵션",
|
|
5202
|
+
"aria/Message,": "메시지,",
|
|
5159
5203
|
"aria/Mute User": "사용자 음소거",
|
|
5160
5204
|
"aria/Notifications": "알림",
|
|
5161
5205
|
"aria/Open Attachment Selector": "첨부 파일 선택기 열기",
|
|
@@ -5224,6 +5268,8 @@ const koTranslations = {
|
|
|
5224
5268
|
"Close dialog": "대화 상자 닫기",
|
|
5225
5269
|
"Close emoji picker": "이모티콘 선택기 닫기",
|
|
5226
5270
|
"Close prompt: {{ title }}": "프롬프트 닫기: {{ title }}",
|
|
5271
|
+
"Command not available while editing": "편집 중에는 명령을 사용할 수 없습니다",
|
|
5272
|
+
"Command not available while replying": "답장 중에는 명령을 사용할 수 없습니다",
|
|
5227
5273
|
Commands: Commands$4,
|
|
5228
5274
|
"Commands matching": "일치하는 명령",
|
|
5229
5275
|
"Connection failure, reconnecting now...": "연결 실패, 지금 다시 연결 중...",
|
|
@@ -5283,6 +5329,8 @@ const koTranslations = {
|
|
|
5283
5329
|
"Failed to end the poll due to {{reason}}": "{{reason}}(으)로 인해 투표 종료에 실패했습니다",
|
|
5284
5330
|
"Failed to jump to the first unread message": "첫 번째 읽지 않은 메시지로 이동하지 못했습니다",
|
|
5285
5331
|
"Failed to leave channel": "채널 나가기에 실패했습니다",
|
|
5332
|
+
"Failed to load channels": "채널을 불러오지 못했습니다",
|
|
5333
|
+
"Failed to load more channels": "채널을 더 불러오지 못했습니다",
|
|
5286
5334
|
"Failed to mark channel as read": "채널을 읽음으로 표시하는 데 실패했습니다",
|
|
5287
5335
|
"Failed to play the recording": "녹음을 재생하지 못했습니다",
|
|
5288
5336
|
"Failed to retrieve location": "위치를 가져오지 못했습니다",
|
|
@@ -5738,7 +5786,9 @@ const nlTranslations = {
|
|
|
5738
5786
|
"aria/Mark messages as read": "Markeer berichten als gelezen",
|
|
5739
5787
|
"aria/Menu": "Menu",
|
|
5740
5788
|
"aria/Message Actions": "Berichtacties",
|
|
5789
|
+
"aria/Message from {{ user }},": "Bericht van {{ user }},",
|
|
5741
5790
|
"aria/Message Options": "Berichtopties",
|
|
5791
|
+
"aria/Message,": "Bericht,",
|
|
5742
5792
|
"aria/Mute User": "Gebruiker dempen",
|
|
5743
5793
|
"aria/Notifications": "Meldingen",
|
|
5744
5794
|
"aria/Open Attachment Selector": "Open bijlage selector",
|
|
@@ -5807,6 +5857,8 @@ const nlTranslations = {
|
|
|
5807
5857
|
"Close dialog": "Dialoog sluiten",
|
|
5808
5858
|
"Close emoji picker": "Sluit de emoji-kiezer",
|
|
5809
5859
|
"Close prompt: {{ title }}": "Prompt sluiten: {{ title }}",
|
|
5860
|
+
"Command not available while editing": "Opdracht niet beschikbaar tijdens bewerken",
|
|
5861
|
+
"Command not available while replying": "Opdracht niet beschikbaar tijdens beantwoorden",
|
|
5810
5862
|
Commands: Commands$3,
|
|
5811
5863
|
"Commands matching": "Bijpassende opdrachten",
|
|
5812
5864
|
"Connection failure, reconnecting now...": "Verbindingsfout, opnieuw verbinden...",
|
|
@@ -5866,6 +5918,8 @@ const nlTranslations = {
|
|
|
5866
5918
|
"Failed to end the poll due to {{reason}}": "Peiling kon niet worden beëindigd vanwege {{reason}}",
|
|
5867
5919
|
"Failed to jump to the first unread message": "Niet gelukt om naar het eerste ongelezen bericht te springen",
|
|
5868
5920
|
"Failed to leave channel": "Kanaal verlaten mislukt",
|
|
5921
|
+
"Failed to load channels": "Kanalen konden niet worden geladen",
|
|
5922
|
+
"Failed to load more channels": "Meer kanalen konden niet worden geladen",
|
|
5869
5923
|
"Failed to mark channel as read": "Kanaal kon niet als gelezen worden gemarkeerd",
|
|
5870
5924
|
"Failed to play the recording": "Kan de opname niet afspelen",
|
|
5871
5925
|
"Failed to retrieve location": "Locatie kon niet worden opgehaald",
|
|
@@ -6346,7 +6400,9 @@ const ptTranslations = {
|
|
|
6346
6400
|
"aria/Mark messages as read": "Marcar mensagens como lidas",
|
|
6347
6401
|
"aria/Menu": "Menu",
|
|
6348
6402
|
"aria/Message Actions": "Ações da mensagem",
|
|
6403
|
+
"aria/Message from {{ user }},": "Mensagem de {{ user }},",
|
|
6349
6404
|
"aria/Message Options": "Opções de mensagem",
|
|
6405
|
+
"aria/Message,": "Mensagem,",
|
|
6350
6406
|
"aria/Mute User": "Silenciar usuário",
|
|
6351
6407
|
"aria/Notifications": "Notificações",
|
|
6352
6408
|
"aria/Open Attachment Selector": "Abrir seletor de anexos",
|
|
@@ -6415,6 +6471,8 @@ const ptTranslations = {
|
|
|
6415
6471
|
"Close dialog": "Fechar diálogo",
|
|
6416
6472
|
"Close emoji picker": "Fechar seletor de emoji",
|
|
6417
6473
|
"Close prompt: {{ title }}": "Fechar prompt: {{ title }}",
|
|
6474
|
+
"Command not available while editing": "Comando não disponível durante a edição",
|
|
6475
|
+
"Command not available while replying": "Comando não disponível durante a resposta",
|
|
6418
6476
|
Commands: Commands$2,
|
|
6419
6477
|
"Commands matching": "Comandos correspondentes",
|
|
6420
6478
|
"Connection failure, reconnecting now...": "Falha de conexão, reconectando agora...",
|
|
@@ -6474,6 +6532,8 @@ const ptTranslations = {
|
|
|
6474
6532
|
"Failed to end the poll due to {{reason}}": "Falha ao encerrar a enquete devido a {{reason}}",
|
|
6475
6533
|
"Failed to jump to the first unread message": "Falha ao pular para a primeira mensagem não lida",
|
|
6476
6534
|
"Failed to leave channel": "Falha ao sair do canal",
|
|
6535
|
+
"Failed to load channels": "Falha ao carregar os canais",
|
|
6536
|
+
"Failed to load more channels": "Falha ao carregar mais canais",
|
|
6477
6537
|
"Failed to mark channel as read": "Falha ao marcar o canal como lido",
|
|
6478
6538
|
"Failed to play the recording": "Falha ao reproduzir a gravação",
|
|
6479
6539
|
"Failed to retrieve location": "Falha ao obter localização",
|
|
@@ -6983,7 +7043,9 @@ const ruTranslations = {
|
|
|
6983
7043
|
"aria/Mark messages as read": "Отметить сообщения как прочитанные",
|
|
6984
7044
|
"aria/Menu": "Меню",
|
|
6985
7045
|
"aria/Message Actions": "Действия с сообщением",
|
|
7046
|
+
"aria/Message from {{ user }},": "Сообщение от {{ user }},",
|
|
6986
7047
|
"aria/Message Options": "Параметры сообщения",
|
|
7048
|
+
"aria/Message,": "Сообщение,",
|
|
6987
7049
|
"aria/Mute User": "Отключить уведомления",
|
|
6988
7050
|
"aria/Notifications": "Уведомления",
|
|
6989
7051
|
"aria/Open Attachment Selector": "Открыть выбор вложений",
|
|
@@ -7052,6 +7114,8 @@ const ruTranslations = {
|
|
|
7052
7114
|
"Close dialog": "Закрыть диалог",
|
|
7053
7115
|
"Close emoji picker": "Закрыть окно выбора смайлов",
|
|
7054
7116
|
"Close prompt: {{ title }}": "Закрыть запрос: {{ title }}",
|
|
7117
|
+
"Command not available while editing": "Команда недоступна при редактировании",
|
|
7118
|
+
"Command not available while replying": "Команда недоступна при ответе",
|
|
7055
7119
|
Commands: Commands$1,
|
|
7056
7120
|
"Commands matching": "Соответствие команд",
|
|
7057
7121
|
"Connection failure, reconnecting now...": "Ошибка соединения, переподключение...",
|
|
@@ -7111,6 +7175,8 @@ const ruTranslations = {
|
|
|
7111
7175
|
"Failed to end the poll due to {{reason}}": "Не удалось завершить опрос из-за {{reason}}",
|
|
7112
7176
|
"Failed to jump to the first unread message": "Не удалось перейти к первому непрочитанному сообщению",
|
|
7113
7177
|
"Failed to leave channel": "Не удалось покинуть канал",
|
|
7178
|
+
"Failed to load channels": "Не удалось загрузить каналы",
|
|
7179
|
+
"Failed to load more channels": "Не удалось загрузить больше каналов",
|
|
7114
7180
|
"Failed to mark channel as read": "Не удалось пометить канал как прочитанный",
|
|
7115
7181
|
"Failed to play the recording": "Не удалось воспроизвести запись",
|
|
7116
7182
|
"Failed to retrieve location": "Не удалось получить местоположение",
|
|
@@ -7598,7 +7664,9 @@ const trTranslations = {
|
|
|
7598
7664
|
"aria/Mark messages as read": "Mesajları okundu olarak işaretle",
|
|
7599
7665
|
"aria/Menu": "Menü",
|
|
7600
7666
|
"aria/Message Actions": "Mesaj eylemleri",
|
|
7667
|
+
"aria/Message from {{ user }},": "{{ user }} adlı kullanıcıdan mesaj,",
|
|
7601
7668
|
"aria/Message Options": "Mesaj Seçenekleri",
|
|
7669
|
+
"aria/Message,": "Mesaj,",
|
|
7602
7670
|
"aria/Mute User": "Kullanıcıyı sustur",
|
|
7603
7671
|
"aria/Notifications": "Bildirimler",
|
|
7604
7672
|
"aria/Open Attachment Selector": "Ek Seçiciyi Aç",
|
|
@@ -7667,6 +7735,8 @@ const trTranslations = {
|
|
|
7667
7735
|
"Close dialog": "İletişim kutusunu kapat",
|
|
7668
7736
|
"Close emoji picker": "Emoji seçiciyi kapat",
|
|
7669
7737
|
"Close prompt: {{ title }}": "İstemi kapat: {{ title }}",
|
|
7738
|
+
"Command not available while editing": "Düzenleme sırasında komut kullanılamaz",
|
|
7739
|
+
"Command not available while replying": "Yanıtlama sırasında komut kullanılamaz",
|
|
7670
7740
|
Commands,
|
|
7671
7741
|
"Commands matching": "Eşleşen komutlar",
|
|
7672
7742
|
"Connection failure, reconnecting now...": "Bağlantı hatası, tekrar bağlanılıyor...",
|
|
@@ -7726,6 +7796,8 @@ const trTranslations = {
|
|
|
7726
7796
|
"Failed to end the poll due to {{reason}}": "{{reason}} nedeniyle anket sonlandırılamadı",
|
|
7727
7797
|
"Failed to jump to the first unread message": "İlk okunmamış mesaja atlamada hata oluştu",
|
|
7728
7798
|
"Failed to leave channel": "Kanaldan çıkılamadı",
|
|
7799
|
+
"Failed to load channels": "Kanallar yüklenemedi",
|
|
7800
|
+
"Failed to load more channels": "Daha fazla kanal yüklenemedi",
|
|
7729
7801
|
"Failed to mark channel as read": "Kanalı okundu olarak işaretleme başarısız oldu",
|
|
7730
7802
|
"Failed to play the recording": "Kayıt oynatılamadı",
|
|
7731
7803
|
"Failed to retrieve location": "Konum alınamadı",
|
|
@@ -8590,6 +8662,19 @@ const translatePollEndFailed = ({
|
|
|
8590
8662
|
t
|
|
8591
8663
|
});
|
|
8592
8664
|
const translateBrowserAudioPlaybackError = ({ options: { notification }, t }) => notification?.message ? t(notification.message) : t("Error reproducing the recording");
|
|
8665
|
+
const translateCommandDisabled = ({
|
|
8666
|
+
options: { notification },
|
|
8667
|
+
t
|
|
8668
|
+
}) => {
|
|
8669
|
+
const reason = normalizeReason(notification);
|
|
8670
|
+
if (reason === "editing") {
|
|
8671
|
+
return t("Command not available while editing");
|
|
8672
|
+
}
|
|
8673
|
+
if (reason === "quoted_message") {
|
|
8674
|
+
return t("Command not available while replying");
|
|
8675
|
+
}
|
|
8676
|
+
return t(notification?.message || "Command not available");
|
|
8677
|
+
};
|
|
8593
8678
|
const translatorsByNotificationType = {
|
|
8594
8679
|
"api:attachment:upload:failed": translateAttachmentUploadFailed,
|
|
8595
8680
|
"api:location:create:failed": ({ t }) => t("Failed to share location"),
|
|
@@ -8605,6 +8690,7 @@ const translatorsByNotificationType = {
|
|
|
8605
8690
|
"validation:attachment:id:missing": ({ t }) => t("Local upload attachment missing local id"),
|
|
8606
8691
|
"validation:attachment:upload:blocked": translateAttachmentUploadBlocked,
|
|
8607
8692
|
"validation:attachment:upload:in-progress": ({ t }) => t("Wait until all attachments have uploaded"),
|
|
8693
|
+
"validation:command:disabled": translateCommandDisabled,
|
|
8608
8694
|
"validation:poll:castVote:limit": ({ t }) => t("Reached the vote limit. Remove an existing vote first.")
|
|
8609
8695
|
};
|
|
8610
8696
|
const translateByNotificationType = ({
|
|
@@ -10030,7 +10116,7 @@ const DialogAnchor = ({
|
|
|
10030
10116
|
useEffect(() => {
|
|
10031
10117
|
if (!open) return;
|
|
10032
10118
|
const hideOnEscape = (event) => {
|
|
10033
|
-
if (event.key !== "Escape") return;
|
|
10119
|
+
if (event.key !== "Escape" || event.defaultPrevented) return;
|
|
10034
10120
|
dialog?.close();
|
|
10035
10121
|
};
|
|
10036
10122
|
document.addEventListener("keyup", hideOnEscape);
|
|
@@ -10135,7 +10221,7 @@ const Avatar = ({
|
|
|
10135
10221
|
}
|
|
10136
10222
|
return initials;
|
|
10137
10223
|
}, [nameString, size]);
|
|
10138
|
-
const showImage = typeof imageUrl === "string" && !error;
|
|
10224
|
+
const showImage = typeof imageUrl === "string" && imageUrl && !error;
|
|
10139
10225
|
return /* @__PURE__ */ jsxs(
|
|
10140
10226
|
"div",
|
|
10141
10227
|
{
|
|
@@ -12058,9 +12144,11 @@ const UnMemoizedMessageTextComponent = (props) => {
|
|
|
12058
12144
|
unsafeHTML
|
|
12059
12145
|
} = useMessageContext();
|
|
12060
12146
|
const renderText$1 = propsRenderText ?? contextRenderText ?? renderText;
|
|
12061
|
-
const { userLanguage } = useTranslationContext("MessageText");
|
|
12147
|
+
const { t, userLanguage } = useTranslationContext("MessageText");
|
|
12062
12148
|
const message = propMessage || contextMessage;
|
|
12063
12149
|
const hasAttachment = messageHasAttachments(message);
|
|
12150
|
+
const messageContextId = useId();
|
|
12151
|
+
const messageTextId = useId();
|
|
12064
12152
|
const messageTextToRender = translationView === "original" ? message.text : getTranslatedMessageText({ language: userLanguage, message }) || message.text;
|
|
12065
12153
|
const messageText = useMemo(
|
|
12066
12154
|
() => renderText$1(messageTextToRender, message.mentioned_users),
|
|
@@ -12070,6 +12158,9 @@ const UnMemoizedMessageTextComponent = (props) => {
|
|
|
12070
12158
|
const innerClass = customInnerClass;
|
|
12071
12159
|
const hasMentionedUsers = Boolean(message.mentioned_users?.length);
|
|
12072
12160
|
const isMentionsInteractionEnabled = hasMentionedUsers && typeof onMentionsClickMessage === "function";
|
|
12161
|
+
const senderName = message.user?.name;
|
|
12162
|
+
const messageContext = senderName ? t("aria/Message from {{ user }},", { user: senderName }) : t("aria/Message,");
|
|
12163
|
+
const messageLabelledBy = `${messageContextId} ${messageTextId}`;
|
|
12073
12164
|
const handleMentionsKeyDown = (event) => {
|
|
12074
12165
|
if (!isMentionsInteractionEnabled || event.key !== "Enter" && event.key !== " ") {
|
|
12075
12166
|
return;
|
|
@@ -12078,21 +12169,33 @@ const UnMemoizedMessageTextComponent = (props) => {
|
|
|
12078
12169
|
onMentionsClickMessage(event);
|
|
12079
12170
|
};
|
|
12080
12171
|
if (!messageTextToRender) return null;
|
|
12081
|
-
return /* @__PURE__ */
|
|
12172
|
+
return /* @__PURE__ */ jsxs(
|
|
12082
12173
|
"div",
|
|
12083
12174
|
{
|
|
12084
|
-
|
|
12085
|
-
|
|
12086
|
-
|
|
12087
|
-
|
|
12088
|
-
|
|
12089
|
-
|
|
12090
|
-
|
|
12091
|
-
|
|
12092
|
-
|
|
12093
|
-
|
|
12175
|
+
"aria-labelledby": isMentionsInteractionEnabled ? void 0 : messageLabelledBy,
|
|
12176
|
+
className: wrapperClass,
|
|
12177
|
+
tabIndex: isMentionsInteractionEnabled ? void 0 : 0,
|
|
12178
|
+
children: [
|
|
12179
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { id: messageContextId, children: messageContext }),
|
|
12180
|
+
/* @__PURE__ */ jsx(
|
|
12181
|
+
"div",
|
|
12182
|
+
{
|
|
12183
|
+
"aria-labelledby": isMentionsInteractionEnabled ? messageLabelledBy : void 0,
|
|
12184
|
+
className: clsx(innerClass, {
|
|
12185
|
+
[` str-chat__message-text-inner--is-emoji`]: messageTextHasEmojisOnly(message) && !message.quoted_message,
|
|
12186
|
+
[`str-chat__message-text-inner--has-attachment`]: hasAttachment
|
|
12187
|
+
}),
|
|
12188
|
+
"data-testid": "message-text-inner-wrapper",
|
|
12189
|
+
onClick: onMentionsClickMessage,
|
|
12190
|
+
onKeyDown: isMentionsInteractionEnabled ? handleMentionsKeyDown : void 0,
|
|
12191
|
+
onMouseOver: onMentionsHoverMessage,
|
|
12192
|
+
tabIndex: isMentionsInteractionEnabled ? 0 : void 0,
|
|
12193
|
+
children: unsafeHTML && message.html ? /* @__PURE__ */ jsx("div", { dangerouslySetInnerHTML: { __html: message.html }, id: messageTextId }) : /* @__PURE__ */ jsx("div", { id: messageTextId, children: messageText })
|
|
12194
|
+
}
|
|
12195
|
+
)
|
|
12196
|
+
]
|
|
12094
12197
|
}
|
|
12095
|
-
)
|
|
12198
|
+
);
|
|
12096
12199
|
};
|
|
12097
12200
|
const MessageText = React.memo(
|
|
12098
12201
|
UnMemoizedMessageTextComponent
|
|
@@ -13873,12 +13976,13 @@ const BaseImage = forwardRef(function BaseImage2({ src, ...props }, ref) {
|
|
|
13873
13976
|
showDownloadButtonOnError = false,
|
|
13874
13977
|
...imgProps
|
|
13875
13978
|
} = props;
|
|
13876
|
-
const [
|
|
13979
|
+
const [failedSrc, setFailedSrc] = useState(null);
|
|
13877
13980
|
const { ImagePlaceholder: ImagePlaceholderComponent = ImagePlaceholder } = useComponentContext();
|
|
13878
13981
|
const sanitizedUrl = useMemo(() => sanitizeUrl(src), [src]);
|
|
13982
|
+
const error = failedSrc === sanitizedUrl;
|
|
13879
13983
|
useEffect(
|
|
13880
13984
|
() => () => {
|
|
13881
|
-
|
|
13985
|
+
setFailedSrc(null);
|
|
13882
13986
|
},
|
|
13883
13987
|
[sanitizedUrl]
|
|
13884
13988
|
);
|
|
@@ -13901,7 +14005,7 @@ const BaseImage = forwardRef(function BaseImage2({ src, ...props }, ref) {
|
|
|
13901
14005
|
alt: propsAlt ?? "",
|
|
13902
14006
|
className: clsx(propsClassName, "str-chat__base-image"),
|
|
13903
14007
|
onError: (e) => {
|
|
13904
|
-
|
|
14008
|
+
setFailedSrc(sanitizedUrl);
|
|
13905
14009
|
propsOnError?.(e);
|
|
13906
14010
|
},
|
|
13907
14011
|
ref,
|
|
@@ -14447,7 +14551,7 @@ const ThumbnailButton = ({
|
|
|
14447
14551
|
const imageUrl = item.imageUrl;
|
|
14448
14552
|
const [isLoadFailed, setIsLoadFailed] = useState(false);
|
|
14449
14553
|
const [isImageLoading, setIsImageLoading] = useState(Boolean(imageUrl));
|
|
14450
|
-
const [
|
|
14554
|
+
const [retrySuffix, setRetrySuffix] = useState("");
|
|
14451
14555
|
const {
|
|
14452
14556
|
onError: itemOnError,
|
|
14453
14557
|
onLoad: itemOnLoad,
|
|
@@ -14459,7 +14563,7 @@ const ThumbnailButton = ({
|
|
|
14459
14563
|
if (showRetryIndicator) {
|
|
14460
14564
|
setIsLoadFailed(false);
|
|
14461
14565
|
setIsImageLoading(true);
|
|
14462
|
-
|
|
14566
|
+
setRetrySuffix(`&retry=${Date.now()}`);
|
|
14463
14567
|
return;
|
|
14464
14568
|
}
|
|
14465
14569
|
onClick();
|
|
@@ -14491,10 +14595,9 @@ const ThumbnailButton = ({
|
|
|
14491
14595
|
setIsLoadFailed(false);
|
|
14492
14596
|
itemOnLoad?.(event);
|
|
14493
14597
|
},
|
|
14494
|
-
src: imageUrl,
|
|
14598
|
+
src: imageUrl ? `${imageUrl}${retrySuffix}` : imageUrl,
|
|
14495
14599
|
...baseImageUsesDefaultBehavior ? { showDownloadButtonOnError: false } : {}
|
|
14496
|
-
}
|
|
14497
|
-
retryCount
|
|
14600
|
+
}
|
|
14498
14601
|
),
|
|
14499
14602
|
showLoadingIndicator && /* @__PURE__ */ jsx(
|
|
14500
14603
|
"div",
|
|
@@ -16170,6 +16273,32 @@ const useMessageComposerBindings = (props) => {
|
|
|
16170
16273
|
textareaRef
|
|
16171
16274
|
};
|
|
16172
16275
|
};
|
|
16276
|
+
const messageComposerStateSelector$4 = ({
|
|
16277
|
+
editedMessage,
|
|
16278
|
+
quotedMessage
|
|
16279
|
+
}) => ({
|
|
16280
|
+
editedMessage,
|
|
16281
|
+
quotedMessage
|
|
16282
|
+
});
|
|
16283
|
+
const useMessageComposerCommands = () => {
|
|
16284
|
+
const messageComposer = useMessageComposerController();
|
|
16285
|
+
const channelConfig = messageComposer.channel.getConfig();
|
|
16286
|
+
const { editedMessage, quotedMessage } = useStateStore(
|
|
16287
|
+
messageComposer.state,
|
|
16288
|
+
messageComposerStateSelector$4
|
|
16289
|
+
);
|
|
16290
|
+
return useMemo(
|
|
16291
|
+
() => (channelConfig?.commands ?? []).filter(
|
|
16292
|
+
(command) => !!command.name
|
|
16293
|
+
).map((command) => ({
|
|
16294
|
+
command,
|
|
16295
|
+
enabled: !messageComposer.isCommandDisabled(command)
|
|
16296
|
+
})),
|
|
16297
|
+
// editedMessage and quotedMessage are necessary in deps for reactivity
|
|
16298
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
16299
|
+
[channelConfig, editedMessage, messageComposer, quotedMessage]
|
|
16300
|
+
);
|
|
16301
|
+
};
|
|
16173
16302
|
const editingAuditStateStateSelector$1 = (state) => state;
|
|
16174
16303
|
const useMessageComposerHasSendableData = () => {
|
|
16175
16304
|
const messageComposer = useMessageComposerController();
|
|
@@ -16409,6 +16538,8 @@ const QuotedMessagePreview = ({
|
|
|
16409
16538
|
) }) : null;
|
|
16410
16539
|
};
|
|
16411
16540
|
const QuotedMessagePreviewUI = ({
|
|
16541
|
+
authorLabel,
|
|
16542
|
+
className,
|
|
16412
16543
|
getQuotedMessageAuthor,
|
|
16413
16544
|
onClick,
|
|
16414
16545
|
onRemove,
|
|
@@ -16485,7 +16616,7 @@ const QuotedMessagePreviewUI = ({
|
|
|
16485
16616
|
"div",
|
|
16486
16617
|
{
|
|
16487
16618
|
"aria-label": isInteractive ? t("aria/Jump to quoted message") : void 0,
|
|
16488
|
-
className: clsx("str-chat__quoted-message-preview", {
|
|
16619
|
+
className: clsx("str-chat__quoted-message-preview", className, {
|
|
16489
16620
|
"str-chat__quoted-message-preview--own": isOwnMessage
|
|
16490
16621
|
}),
|
|
16491
16622
|
"data-testid": "quoted-message-preview",
|
|
@@ -16496,7 +16627,7 @@ const QuotedMessagePreviewUI = ({
|
|
|
16496
16627
|
children: [
|
|
16497
16628
|
/* @__PURE__ */ jsx(QuotedMessageIndicator, { isOwnMessage }),
|
|
16498
16629
|
/* @__PURE__ */ jsxs("div", { className: "str-chat__quoted-message-preview__content", children: [
|
|
16499
|
-
/* @__PURE__ */ jsx("div", { className: "str-chat__quoted-message-preview__author", children: isOwnMessage ? t("You") : authorName ? t("Reply to {{ authorName }}", { authorName }) : t("Reply") }),
|
|
16630
|
+
/* @__PURE__ */ jsx("div", { className: "str-chat__quoted-message-preview__author", children: authorLabel ?? (isOwnMessage ? t("You") : authorName ? t("Reply to {{ authorName }}", { authorName }) : t("Reply")) }),
|
|
16500
16631
|
/* @__PURE__ */ jsxs(
|
|
16501
16632
|
"div",
|
|
16502
16633
|
{
|
|
@@ -16634,6 +16765,7 @@ const StreamedMessageText = (props) => {
|
|
|
16634
16765
|
);
|
|
16635
16766
|
};
|
|
16636
16767
|
const DEFAULT_DROPDOWN_ITEM_SELECTOR = '[role="option"]:not(:disabled), [role="menuitem"]:not(:disabled), button:not(:disabled), a:not(:disabled)';
|
|
16768
|
+
const isEditableTarget = (target) => target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement || target instanceof HTMLElement && target.isContentEditable;
|
|
16637
16769
|
const DropdownContext = React.createContext({
|
|
16638
16770
|
close: () => null
|
|
16639
16771
|
});
|
|
@@ -16645,6 +16777,7 @@ const useDropdownContext = () => React.useContext(DropdownContext);
|
|
|
16645
16777
|
const Dropdown = ({
|
|
16646
16778
|
children,
|
|
16647
16779
|
className,
|
|
16780
|
+
matchReferenceWidth = false,
|
|
16648
16781
|
onClose,
|
|
16649
16782
|
onOpen,
|
|
16650
16783
|
placement = "bottom",
|
|
@@ -16711,17 +16844,29 @@ const Dropdown = ({
|
|
|
16711
16844
|
}),
|
|
16712
16845
|
[]
|
|
16713
16846
|
);
|
|
16847
|
+
const escapeConsumedRef = useRef(false);
|
|
16714
16848
|
const handleKeyDown = useCallback(
|
|
16715
16849
|
(event) => {
|
|
16716
16850
|
if (event.key === "Escape") {
|
|
16717
16851
|
event.preventDefault();
|
|
16852
|
+
event.stopPropagation();
|
|
16853
|
+
escapeConsumedRef.current = true;
|
|
16718
16854
|
close();
|
|
16719
16855
|
return;
|
|
16720
16856
|
}
|
|
16857
|
+
if (isEditableTarget(event.target)) {
|
|
16858
|
+
return;
|
|
16859
|
+
}
|
|
16721
16860
|
rovingFocusKeyDownHandler(event);
|
|
16722
16861
|
},
|
|
16723
16862
|
[close, rovingFocusKeyDownHandler]
|
|
16724
16863
|
);
|
|
16864
|
+
const suppressEscapeKeyUp = useCallback((event) => {
|
|
16865
|
+
if (event.key === "Escape" && escapeConsumedRef.current) {
|
|
16866
|
+
escapeConsumedRef.current = false;
|
|
16867
|
+
event.stopPropagation();
|
|
16868
|
+
}
|
|
16869
|
+
}, []);
|
|
16725
16870
|
const DropdownTriggerComponent = TriggerComponent;
|
|
16726
16871
|
const trigger = DropdownTriggerComponent ? /* @__PURE__ */ jsx(
|
|
16727
16872
|
DropdownTriggerComponent,
|
|
@@ -16738,10 +16883,12 @@ const Dropdown = ({
|
|
|
16738
16883
|
className: clsx("str-chat__dropdown__items", className),
|
|
16739
16884
|
onClick: close,
|
|
16740
16885
|
onKeyDown: handleKeyDown,
|
|
16886
|
+
onKeyUpCapture: suppressEscapeKeyUp,
|
|
16741
16887
|
ref: setFloatingElement,
|
|
16742
16888
|
role: "menu",
|
|
16743
16889
|
style: {
|
|
16744
16890
|
left: x ?? 0,
|
|
16891
|
+
minWidth: matchReferenceWidth ? resolvedReferenceElement.getBoundingClientRect().width : void 0,
|
|
16745
16892
|
position: strategy,
|
|
16746
16893
|
top: y ?? 0
|
|
16747
16894
|
},
|
|
@@ -19142,19 +19289,20 @@ const CommandsMenu = () => {
|
|
|
19142
19289
|
const { closeMenu } = useContextMenuContext();
|
|
19143
19290
|
const messageComposer = useMessageComposerController();
|
|
19144
19291
|
const { textareaRef } = useMessageComposerContext();
|
|
19145
|
-
const
|
|
19146
|
-
const
|
|
19147
|
-
() =>
|
|
19148
|
-
(
|
|
19149
|
-
)
|
|
19150
|
-
[
|
|
19292
|
+
const commands = useMessageComposerCommands();
|
|
19293
|
+
const sortedCommands = useMemo(
|
|
19294
|
+
() => [...commands].sort(
|
|
19295
|
+
(a, b) => (a.command.name ?? "").localeCompare(b.command.name ?? "")
|
|
19296
|
+
),
|
|
19297
|
+
[commands]
|
|
19151
19298
|
);
|
|
19152
|
-
return /* @__PURE__ */ jsx(Fragment, { children:
|
|
19299
|
+
return /* @__PURE__ */ jsx(Fragment, { children: sortedCommands.map(({ command, enabled }) => /* @__PURE__ */ jsx(
|
|
19153
19300
|
CommandContextMenuItem,
|
|
19154
19301
|
{
|
|
19155
19302
|
command,
|
|
19303
|
+
enabled,
|
|
19156
19304
|
onClick: () => {
|
|
19157
|
-
if (!command.name) return;
|
|
19305
|
+
if (!command.name || !enabled) return;
|
|
19158
19306
|
messageComposer.textComposer.setCommand(command);
|
|
19159
19307
|
closeMenu();
|
|
19160
19308
|
requestAnimationFrame(() => textareaRef.current?.focus());
|
|
@@ -19192,16 +19340,21 @@ const useCommandTranslation = (command) => {
|
|
|
19192
19340
|
const CommandContextMenuItem = ({
|
|
19193
19341
|
className,
|
|
19194
19342
|
command,
|
|
19343
|
+
enabled = true,
|
|
19195
19344
|
...props
|
|
19196
19345
|
}) => {
|
|
19197
19346
|
const { args, description } = useCommandTranslation(command);
|
|
19198
|
-
const details = useMemo(
|
|
19347
|
+
const details = useMemo(
|
|
19348
|
+
() => args ? `/${command.name} ${args}` : `/${command.name}`,
|
|
19349
|
+
[args, command.name]
|
|
19350
|
+
);
|
|
19199
19351
|
return /* @__PURE__ */ createElement(
|
|
19200
19352
|
ContextMenuButton,
|
|
19201
19353
|
{
|
|
19202
19354
|
...props,
|
|
19203
19355
|
className: clsx("str-chat__context-menu__button--command", className),
|
|
19204
19356
|
details,
|
|
19357
|
+
disabled: !enabled,
|
|
19205
19358
|
Icon: icons[command.name],
|
|
19206
19359
|
key: command.name,
|
|
19207
19360
|
label: command.name,
|
|
@@ -19274,11 +19427,14 @@ const DefaultAttachmentSelectorComponents = {
|
|
|
19274
19427
|
Command({ submenuHeader, submenuItems }) {
|
|
19275
19428
|
const { t } = useTranslationContext();
|
|
19276
19429
|
const { openSubmenu } = useContextMenuContext();
|
|
19430
|
+
const commands = useMessageComposerCommands();
|
|
19431
|
+
const hasEnabledCommands = commands.some(({ enabled }) => enabled);
|
|
19277
19432
|
const hasSubmenu = !!submenuItems;
|
|
19278
19433
|
return /* @__PURE__ */ jsx(
|
|
19279
19434
|
ContextMenuButton,
|
|
19280
19435
|
{
|
|
19281
|
-
className: "str-chat__attachment-selector-actions-menu__button str-chat__attachment-selector-actions-
|
|
19436
|
+
className: "str-chat__attachment-selector-actions-menu__button str-chat__attachment-selector-actions-menu__commands-button",
|
|
19437
|
+
disabled: !hasEnabledCommands,
|
|
19282
19438
|
hasSubMenu: hasSubmenu,
|
|
19283
19439
|
Icon: IconCommand,
|
|
19284
19440
|
onClick: (event) => {
|
|
@@ -20580,7 +20736,17 @@ const DefaultStartRecordingAudioButton = forwardRef(function StartRecordingAudio
|
|
|
20580
20736
|
const EditedMessagePreview = ({
|
|
20581
20737
|
message,
|
|
20582
20738
|
onCancel
|
|
20583
|
-
}) =>
|
|
20739
|
+
}) => {
|
|
20740
|
+
const { t } = useTranslationContext();
|
|
20741
|
+
return /* @__PURE__ */ jsx(
|
|
20742
|
+
QuotedMessagePreviewUI,
|
|
20743
|
+
{
|
|
20744
|
+
authorLabel: t("Edit Message"),
|
|
20745
|
+
onRemove: onCancel,
|
|
20746
|
+
quotedMessage: message
|
|
20747
|
+
}
|
|
20748
|
+
);
|
|
20749
|
+
};
|
|
20584
20750
|
const stateSelector = (state) => ({
|
|
20585
20751
|
showReplyInChannel: state.showReplyInChannel
|
|
20586
20752
|
});
|
|
@@ -20622,14 +20788,25 @@ const SendToChannelCheckbox = () => {
|
|
|
20622
20788
|
}
|
|
20623
20789
|
);
|
|
20624
20790
|
};
|
|
20791
|
+
const messageComposerStateSelector$3 = ({
|
|
20792
|
+
editedMessage,
|
|
20793
|
+
quotedMessage
|
|
20794
|
+
}) => ({
|
|
20795
|
+
editedMessage,
|
|
20796
|
+
quotedMessage
|
|
20797
|
+
});
|
|
20625
20798
|
const CommandItem = (props) => {
|
|
20626
|
-
const { entity, focused: _, ...buttonProps } = props;
|
|
20799
|
+
const { enabled, entity, focused: _, ...buttonProps } = props;
|
|
20800
|
+
const messageComposer = useMessageComposerController();
|
|
20801
|
+
useStateStore(messageComposer.state, messageComposerStateSelector$3);
|
|
20627
20802
|
if (!entity.name) return null;
|
|
20803
|
+
const resolvedEnabled = enabled ?? !messageComposer.isCommandDisabled(entity);
|
|
20628
20804
|
return /* @__PURE__ */ jsx(
|
|
20629
20805
|
CommandContextMenuItem,
|
|
20630
20806
|
{
|
|
20631
20807
|
...buttonProps,
|
|
20632
|
-
command: entity
|
|
20808
|
+
command: entity,
|
|
20809
|
+
enabled: resolvedEnabled
|
|
20633
20810
|
}
|
|
20634
20811
|
);
|
|
20635
20812
|
};
|
|
@@ -20787,12 +20964,17 @@ const SuggestionList = ({
|
|
|
20787
20964
|
} = useComponentContext();
|
|
20788
20965
|
const { textareaRef } = useMessageComposerContext();
|
|
20789
20966
|
const messageComposer = useMessageComposerController();
|
|
20967
|
+
const commands = useMessageComposerCommands();
|
|
20790
20968
|
const { textComposer } = messageComposer;
|
|
20791
20969
|
const { selection, suggestions } = useStateStore(
|
|
20792
20970
|
textComposer.state,
|
|
20793
20971
|
textComposerStateSelector$3
|
|
20794
20972
|
);
|
|
20795
20973
|
const { items } = useStateStore(suggestions?.searchSource.state, searchSourceStateSelector$5) ?? {};
|
|
20974
|
+
const hasEnabledCommandSuggestions = useMemo(
|
|
20975
|
+
() => suggestions?.searchSource.type !== "commands" || commands.some(({ enabled }) => enabled),
|
|
20976
|
+
[commands, suggestions?.searchSource.type]
|
|
20977
|
+
);
|
|
20796
20978
|
const [container, setContainer] = useState(null);
|
|
20797
20979
|
const caretRectRef = useRef(null);
|
|
20798
20980
|
const virtualCaretReference = useMemo(
|
|
@@ -20888,7 +21070,8 @@ const SuggestionList = ({
|
|
|
20888
21070
|
update,
|
|
20889
21071
|
virtualCaretReference
|
|
20890
21072
|
]);
|
|
20891
|
-
if (!suggestions || !items?.length || !component
|
|
21073
|
+
if (!suggestions || !items?.length || !component || !hasEnabledCommandSuggestions)
|
|
21074
|
+
return null;
|
|
20892
21075
|
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");
|
|
20893
21076
|
return /* @__PURE__ */ jsx(
|
|
20894
21077
|
"div",
|
|
@@ -20965,6 +21148,7 @@ const attachmentManagerStateSelector$1 = (state) => ({
|
|
|
20965
21148
|
attachments: state.attachments
|
|
20966
21149
|
});
|
|
20967
21150
|
const defaultShouldSubmit = (event) => event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing;
|
|
21151
|
+
const shouldBackspaceExitCommandMode = (text2) => text2.length === 0;
|
|
20968
21152
|
const TextareaComposer = ({
|
|
20969
21153
|
className,
|
|
20970
21154
|
closeSuggestionsOnClickOutside,
|
|
@@ -21051,6 +21235,7 @@ const TextareaComposer = ({
|
|
|
21051
21235
|
onKeyDown(event);
|
|
21052
21236
|
return;
|
|
21053
21237
|
}
|
|
21238
|
+
const textareaValue = textareaRef.current?.value ?? event.currentTarget.value;
|
|
21054
21239
|
if (textComposer.suggestions && textComposer.suggestions.searchSource.items?.length) {
|
|
21055
21240
|
if (event.key === "Escape") return textComposer.closeSuggestions();
|
|
21056
21241
|
const loadedItems = textComposer.suggestions.searchSource.items;
|
|
@@ -21082,6 +21267,9 @@ const TextareaComposer = ({
|
|
|
21082
21267
|
return nextIndex;
|
|
21083
21268
|
});
|
|
21084
21269
|
}
|
|
21270
|
+
} else if (textComposer.command && (event.key === "Escape" || event.key === "Backspace" && shouldBackspaceExitCommandMode(textareaValue))) {
|
|
21271
|
+
event.preventDefault();
|
|
21272
|
+
textComposer.clearCommand();
|
|
21085
21273
|
} else if (shouldSubmit(event) && textareaRef.current && messageComposer.hasSendableData) {
|
|
21086
21274
|
if (event.key === "Enter") {
|
|
21087
21275
|
event.preventDefault();
|
|
@@ -21252,6 +21440,7 @@ const WithDragAndDropUpload = ({
|
|
|
21252
21440
|
disabled: isWithinMessageComposerContext ? !isUploadEnabled || isCooldownActive : false,
|
|
21253
21441
|
multiple: multipleUploads,
|
|
21254
21442
|
noClick: true,
|
|
21443
|
+
noKeyboard: true,
|
|
21255
21444
|
onDrop: isWithinMessageComposerContext ? messageComposer.attachmentManager.uploadFiles : handleDrop
|
|
21256
21445
|
});
|
|
21257
21446
|
if (dragAndDropUploadContext.subscribeToDrop !== null) {
|
|
@@ -22174,6 +22363,7 @@ const defaultReactionOptions = {
|
|
|
22174
22363
|
}
|
|
22175
22364
|
}
|
|
22176
22365
|
};
|
|
22366
|
+
const getHasExtendedReactions = (reactionOptions) => !Array.isArray(reactionOptions) && typeof reactionOptions.extended !== "undefined" && Object.keys(reactionOptions.extended).length > 0;
|
|
22177
22367
|
const stableOwnReactions = [];
|
|
22178
22368
|
const ReactionSelector = (props) => {
|
|
22179
22369
|
const {
|
|
@@ -22219,6 +22409,7 @@ const ReactionSelector = (props) => {
|
|
|
22219
22409
|
})
|
|
22220
22410
|
);
|
|
22221
22411
|
}, [reactionOptions]);
|
|
22412
|
+
const hasExtendedReactions = getHasExtendedReactions(reactionOptions);
|
|
22222
22413
|
return /* @__PURE__ */ jsx(
|
|
22223
22414
|
"div",
|
|
22224
22415
|
{
|
|
@@ -22256,7 +22447,7 @@ const ReactionSelector = (props) => {
|
|
|
22256
22447
|
)
|
|
22257
22448
|
}
|
|
22258
22449
|
),
|
|
22259
|
-
/* @__PURE__ */ jsx(
|
|
22450
|
+
hasExtendedReactions && /* @__PURE__ */ jsx(
|
|
22260
22451
|
Button,
|
|
22261
22452
|
{
|
|
22262
22453
|
appearance: "outline",
|
|
@@ -22449,6 +22640,7 @@ const MessageReactionsDetail = ({
|
|
|
22449
22640
|
reactionDetailsSort: contextReactionDetailsSort
|
|
22450
22641
|
} = useMessageContext(MessageReactionsDetail.name);
|
|
22451
22642
|
const reactionDetailsSort = propReactionDetailsSort ?? contextReactionDetailsSort ?? defaultReactionDetailsSort;
|
|
22643
|
+
const hasExtendedReactions = getHasExtendedReactions(reactionOptions);
|
|
22452
22644
|
const {
|
|
22453
22645
|
isLoading: areReactionsLoading,
|
|
22454
22646
|
reactions: reactionDetails,
|
|
@@ -22495,7 +22687,7 @@ const MessageReactionsDetail = ({
|
|
|
22495
22687
|
className: "str-chat__message-reactions-detail__reaction-type-list",
|
|
22496
22688
|
"data-testid": "reaction-type-list",
|
|
22497
22689
|
children: [
|
|
22498
|
-
/* @__PURE__ */ jsx("li", { className: "str-chat__message-reactions-detail__reaction-type-list-item", children: /* @__PURE__ */ jsx(
|
|
22690
|
+
hasExtendedReactions && /* @__PURE__ */ jsx("li", { className: "str-chat__message-reactions-detail__reaction-type-list-item", children: /* @__PURE__ */ jsx(
|
|
22499
22691
|
"button",
|
|
22500
22692
|
{
|
|
22501
22693
|
"aria-label": t("Add reaction"),
|
|
@@ -26040,7 +26232,7 @@ const UnMemoizedScrollToLatestMessageButton = (props) => {
|
|
|
26040
26232
|
/* @__PURE__ */ jsx(
|
|
26041
26233
|
Button,
|
|
26042
26234
|
{
|
|
26043
|
-
appearance: "
|
|
26235
|
+
appearance: "ghost",
|
|
26044
26236
|
"aria-label": t("aria/Jump to latest message"),
|
|
26045
26237
|
"aria-live": "polite",
|
|
26046
26238
|
circular: true,
|
|
@@ -27085,18 +27277,29 @@ const useConnectionRecoveredListener = (forceUpdate) => {
|
|
|
27085
27277
|
};
|
|
27086
27278
|
const RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS = 5e3;
|
|
27087
27279
|
const MIN_RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS = 2e3;
|
|
27280
|
+
const mapPredefinedFilterSortToChannelSort = (sort) => sort.map(({ direction = 1, field }) => ({
|
|
27281
|
+
[field]: direction
|
|
27282
|
+
}));
|
|
27088
27283
|
const usePaginatedChannels = (client, filters, sort, options, activeChannelHandler, recoveryThrottleIntervalMs = RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS, customQueryChannels) => {
|
|
27284
|
+
const { addNotification } = useNotificationApi();
|
|
27089
27285
|
const {
|
|
27090
27286
|
channelsQueryState: { error, setError, setQueryInProgress }
|
|
27091
27287
|
} = useChatContext("usePaginatedChannels");
|
|
27288
|
+
const { t } = useTranslationContext();
|
|
27092
27289
|
const [channels, setChannels] = useState([]);
|
|
27093
27290
|
const [hasNextPage, setHasNextPage] = useState(true);
|
|
27291
|
+
const [responseFilters, setResponseFilters] = useState(
|
|
27292
|
+
void 0
|
|
27293
|
+
);
|
|
27294
|
+
const [responseSort, setResponseSort] = useState(void 0);
|
|
27094
27295
|
const lastRecoveryTimestamp = useRef(void 0);
|
|
27095
27296
|
const recoveryThrottleInterval = recoveryThrottleIntervalMs < MIN_RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS ? MIN_RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS : recoveryThrottleIntervalMs ?? RECOVER_LOADED_CHANNELS_THROTTLE_INTERVAL_IN_MS;
|
|
27096
27297
|
const filterString = useMemo(() => JSON.stringify(filters), [filters]);
|
|
27097
27298
|
const sortString = useMemo(() => JSON.stringify(sort), [sort]);
|
|
27098
27299
|
const queryChannels = async (queryType = "load-more") => {
|
|
27099
27300
|
setError(null);
|
|
27301
|
+
const offset = queryType === "reload" ? 0 : channels.length;
|
|
27302
|
+
const isFirstPage = offset === 0;
|
|
27100
27303
|
if (queryType === "reload") {
|
|
27101
27304
|
setChannels([]);
|
|
27102
27305
|
}
|
|
@@ -27109,8 +27312,9 @@ const usePaginatedChannels = (client, filters, sort, options, activeChannelHandl
|
|
|
27109
27312
|
setChannels,
|
|
27110
27313
|
setHasNextPage
|
|
27111
27314
|
});
|
|
27315
|
+
setResponseFilters(void 0);
|
|
27316
|
+
setResponseSort(void 0);
|
|
27112
27317
|
} else {
|
|
27113
|
-
const offset = queryType === "reload" ? 0 : channels.length;
|
|
27114
27318
|
const newOptions = {
|
|
27115
27319
|
offset,
|
|
27116
27320
|
...options
|
|
@@ -27118,18 +27322,37 @@ const usePaginatedChannels = (client, filters, sort, options, activeChannelHandl
|
|
|
27118
27322
|
const channelQueryResponse = await client.queryChannels(
|
|
27119
27323
|
filters,
|
|
27120
27324
|
sort || {},
|
|
27121
|
-
newOptions
|
|
27325
|
+
newOptions,
|
|
27326
|
+
{ withResponse: true }
|
|
27122
27327
|
);
|
|
27123
|
-
const newChannels = queryType === "reload" ? channelQueryResponse : uniqBy([...channels, ...channelQueryResponse], "cid");
|
|
27328
|
+
const newChannels = queryType === "reload" ? channelQueryResponse.channels : uniqBy([...channels, ...channelQueryResponse.channels], "cid");
|
|
27124
27329
|
setChannels(newChannels);
|
|
27125
|
-
setHasNextPage(channelQueryResponse.length >= (newOptions.limit ?? 1));
|
|
27330
|
+
setHasNextPage(channelQueryResponse.channels.length >= (newOptions.limit ?? 1));
|
|
27331
|
+
const predefinedFilter = channelQueryResponse.predefined_filter;
|
|
27332
|
+
const nextResponseFilters = predefinedFilter ? predefinedFilter.filter : void 0;
|
|
27333
|
+
const nextResponseSort = predefinedFilter?.sort ? mapPredefinedFilterSortToChannelSort(predefinedFilter.sort) : void 0;
|
|
27334
|
+
setResponseFilters(nextResponseFilters);
|
|
27335
|
+
setResponseSort(nextResponseSort);
|
|
27126
27336
|
if (!offset && activeChannelHandler) {
|
|
27127
|
-
activeChannelHandler(newChannels, setChannels
|
|
27337
|
+
activeChannelHandler(newChannels, setChannels, {
|
|
27338
|
+
filters: nextResponseFilters ?? filters,
|
|
27339
|
+
sort: nextResponseSort ?? sort
|
|
27340
|
+
});
|
|
27128
27341
|
}
|
|
27129
27342
|
}
|
|
27130
27343
|
} catch (error2) {
|
|
27131
27344
|
console.warn(error2);
|
|
27132
|
-
|
|
27345
|
+
addNotification({
|
|
27346
|
+
emitter: "ChannelList",
|
|
27347
|
+
error: error2 instanceof Error ? error2 : void 0,
|
|
27348
|
+
message: isFirstPage ? t("Failed to load channels") : t("Failed to load more channels"),
|
|
27349
|
+
severity: "error",
|
|
27350
|
+
targetPanels: ["channel-list"],
|
|
27351
|
+
type: isFirstPage ? "api:channel-list:load:failed" : "api:channel-list:load-more:failed"
|
|
27352
|
+
});
|
|
27353
|
+
if (isFirstPage) {
|
|
27354
|
+
setError(error2);
|
|
27355
|
+
}
|
|
27133
27356
|
}
|
|
27134
27357
|
setQueryInProgress(null);
|
|
27135
27358
|
};
|
|
@@ -27154,8 +27377,12 @@ const usePaginatedChannels = (client, filters, sort, options, activeChannelHandl
|
|
|
27154
27377
|
useEffect(() => {
|
|
27155
27378
|
queryChannels("reload");
|
|
27156
27379
|
}, [filterString, sortString]);
|
|
27380
|
+
const effectiveFilters = responseFilters ?? filters;
|
|
27381
|
+
const effectiveSort = responseSort ?? sort;
|
|
27157
27382
|
return {
|
|
27158
27383
|
channels,
|
|
27384
|
+
effectiveFilters,
|
|
27385
|
+
effectiveSort,
|
|
27159
27386
|
hasNextPage,
|
|
27160
27387
|
loadNextPage,
|
|
27161
27388
|
setChannels
|
|
@@ -28301,7 +28528,7 @@ const UnMemoizedChannelList = (props) => {
|
|
|
28301
28528
|
searchController.state,
|
|
28302
28529
|
searchControllerStateSelector
|
|
28303
28530
|
);
|
|
28304
|
-
const activeChannelHandler = async (channels2, setChannels2) => {
|
|
28531
|
+
const activeChannelHandler = async (channels2, setChannels2, effectiveQueryParams) => {
|
|
28305
28532
|
if (!channels2.length) {
|
|
28306
28533
|
return;
|
|
28307
28534
|
}
|
|
@@ -28319,7 +28546,7 @@ const UnMemoizedChannelList = (props) => {
|
|
|
28319
28546
|
const newChannels = moveChannelUpwards({
|
|
28320
28547
|
channels: channels2,
|
|
28321
28548
|
channelToMove: customActiveChannelObject,
|
|
28322
|
-
sort
|
|
28549
|
+
sort: effectiveQueryParams.sort
|
|
28323
28550
|
});
|
|
28324
28551
|
setChannels2(newChannels);
|
|
28325
28552
|
return;
|
|
@@ -28330,7 +28557,14 @@ const UnMemoizedChannelList = (props) => {
|
|
|
28330
28557
|
}
|
|
28331
28558
|
};
|
|
28332
28559
|
const forceUpdate = useCallback(() => setChannelUpdateCount((count) => count + 1), []);
|
|
28333
|
-
const {
|
|
28560
|
+
const {
|
|
28561
|
+
channels,
|
|
28562
|
+
effectiveFilters,
|
|
28563
|
+
effectiveSort,
|
|
28564
|
+
hasNextPage,
|
|
28565
|
+
loadNextPage,
|
|
28566
|
+
setChannels
|
|
28567
|
+
} = usePaginatedChannels(
|
|
28334
28568
|
client,
|
|
28335
28569
|
filters || DEFAULT_FILTERS,
|
|
28336
28570
|
sort || DEFAULT_SORT,
|
|
@@ -28342,7 +28576,11 @@ const UnMemoizedChannelList = (props) => {
|
|
|
28342
28576
|
const loadedChannels = channelRenderFilterFn ? channelRenderFilterFn(channels) : channels;
|
|
28343
28577
|
const { customHandler, defaultHandler } = usePrepareShapeHandlers({
|
|
28344
28578
|
allowNewMessagesFromUnfilteredChannels,
|
|
28345
|
-
|
|
28579
|
+
// `effectiveFilters`/`effectiveSort` reflect the backend-resolved
|
|
28580
|
+
// `predefined_filter` metadata when `options.predefined_filter` is in use.
|
|
28581
|
+
// For non-predefined queries they fall back to the caller-supplied
|
|
28582
|
+
// `filters`/`sort` props so behavior is unchanged.
|
|
28583
|
+
filters: effectiveFilters,
|
|
28346
28584
|
lockChannelOrder,
|
|
28347
28585
|
onAddedToChannel,
|
|
28348
28586
|
onChannelDeleted,
|
|
@@ -28354,7 +28592,7 @@ const UnMemoizedChannelList = (props) => {
|
|
|
28354
28592
|
onMessageNewHandler,
|
|
28355
28593
|
onRemovedFromChannel,
|
|
28356
28594
|
setChannels,
|
|
28357
|
-
sort
|
|
28595
|
+
sort: effectiveSort
|
|
28358
28596
|
// TODO: implement
|
|
28359
28597
|
// customHandleChannelListShape
|
|
28360
28598
|
});
|
|
@@ -28904,12 +29142,29 @@ const ChannelListItemActionButtons = () => {
|
|
|
28904
29142
|
const { t } = useTranslationContext();
|
|
28905
29143
|
const { channel } = useChannelListItemContext();
|
|
28906
29144
|
const [referenceElement, setReferenceElement] = React.useState(null);
|
|
29145
|
+
const [isRestoringFocus, setIsRestoringFocus] = React.useState(false);
|
|
28907
29146
|
const dialogId2 = ChannelListItemActionButtons.getDialogId({
|
|
28908
29147
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
28909
29148
|
channelId: channel.id
|
|
28910
29149
|
});
|
|
28911
29150
|
const { dialog, dialogManager } = useDialogOnNearestManager({ id: dialogId2 });
|
|
28912
29151
|
const dialogIsOpen = useDialogIsOpen(dialogId2, dialogManager?.id);
|
|
29152
|
+
const closeContextMenu = React.useCallback(() => {
|
|
29153
|
+
setIsRestoringFocus(true);
|
|
29154
|
+
dialog?.close();
|
|
29155
|
+
requestAnimationFrame(() => {
|
|
29156
|
+
if (!referenceElement?.isConnected) {
|
|
29157
|
+
setIsRestoringFocus(false);
|
|
29158
|
+
return;
|
|
29159
|
+
}
|
|
29160
|
+
referenceElement.focus();
|
|
29161
|
+
requestAnimationFrame(() => {
|
|
29162
|
+
if (document.activeElement !== referenceElement) {
|
|
29163
|
+
setIsRestoringFocus(false);
|
|
29164
|
+
}
|
|
29165
|
+
});
|
|
29166
|
+
});
|
|
29167
|
+
}, [dialog, referenceElement]);
|
|
28913
29168
|
const filteredActionSet = useBaseChannelActionSetFilter(defaultChannelActionSet);
|
|
28914
29169
|
const { dropdownActionSet, quickActionSet, quickDropdownToggleAction } = useSplitActionSet(filteredActionSet);
|
|
28915
29170
|
if (quickActionSet.length + dropdownActionSet.length === 0) {
|
|
@@ -28919,9 +29174,12 @@ const ChannelListItemActionButtons = () => {
|
|
|
28919
29174
|
"div",
|
|
28920
29175
|
{
|
|
28921
29176
|
className: clsx("str-chat__channel-list-item__action-buttons", {
|
|
28922
|
-
"str-chat__channel-list-item__action-buttons--active": dialogIsOpen
|
|
29177
|
+
"str-chat__channel-list-item__action-buttons--active": dialogIsOpen || isRestoringFocus
|
|
28923
29178
|
}),
|
|
28924
29179
|
"data-testid": "channel-list-item-action-buttons",
|
|
29180
|
+
onFocusCapture: () => {
|
|
29181
|
+
setIsRestoringFocus(false);
|
|
29182
|
+
},
|
|
28925
29183
|
children: [
|
|
28926
29184
|
quickDropdownToggleAction && dropdownActionSet.length > 0 && /* @__PURE__ */ jsx(quickDropdownToggleAction.Component, { ref: setReferenceElement }),
|
|
28927
29185
|
quickActionSet.map(({ Component: Component2, type }) => /* @__PURE__ */ jsx(Component2, {}, type)),
|
|
@@ -28933,7 +29191,7 @@ const ChannelListItemActionButtons = () => {
|
|
|
28933
29191
|
"data-testid": "channel-list-item-context-menu",
|
|
28934
29192
|
dialogManagerId: dialogManager?.id,
|
|
28935
29193
|
id: dialog.id,
|
|
28936
|
-
onClose:
|
|
29194
|
+
onClose: closeContextMenu,
|
|
28937
29195
|
placement: "bottom-start",
|
|
28938
29196
|
referenceElement,
|
|
28939
29197
|
tabIndex: -1,
|
|
@@ -29175,6 +29433,7 @@ const UnMemoizedChannelListItemUI = (props) => {
|
|
|
29175
29433
|
messageDeliveryStatus,
|
|
29176
29434
|
muted,
|
|
29177
29435
|
onSelect: customOnSelectChannel,
|
|
29436
|
+
pinned,
|
|
29178
29437
|
setActiveChannel,
|
|
29179
29438
|
unread,
|
|
29180
29439
|
watchers
|
|
@@ -29197,7 +29456,6 @@ const UnMemoizedChannelListItemUI = (props) => {
|
|
|
29197
29456
|
}
|
|
29198
29457
|
};
|
|
29199
29458
|
return /* @__PURE__ */ jsxs("div", { className: "str-chat__channel-list-item-container", children: [
|
|
29200
|
-
/* @__PURE__ */ jsx(ChannelListItemActionButtons$1, {}),
|
|
29201
29459
|
/* @__PURE__ */ jsxs(
|
|
29202
29460
|
"button",
|
|
29203
29461
|
{
|
|
@@ -29207,8 +29465,11 @@ const UnMemoizedChannelListItemUI = (props) => {
|
|
|
29207
29465
|
"aria-selected": active,
|
|
29208
29466
|
className: clsx(
|
|
29209
29467
|
"str-chat__channel-list-item",
|
|
29210
|
-
|
|
29211
|
-
|
|
29468
|
+
{
|
|
29469
|
+
"str-chat__channel-list-item--muted": muted,
|
|
29470
|
+
"str-chat__channel-list-item--pinned": pinned,
|
|
29471
|
+
"str-chat__channel-list-item--unread": typeof unread === "number" && unread > 0
|
|
29472
|
+
},
|
|
29212
29473
|
customClassName
|
|
29213
29474
|
),
|
|
29214
29475
|
"data-testid": "channel-list-item-button",
|
|
@@ -29229,6 +29490,7 @@ const UnMemoizedChannelListItemUI = (props) => {
|
|
|
29229
29490
|
/* @__PURE__ */ jsxs("div", { className: "str-chat__channel-list-item-data__first-row", children: [
|
|
29230
29491
|
/* @__PURE__ */ jsxs("div", { className: "str-chat__channel-list-item-data__title", children: [
|
|
29231
29492
|
/* @__PURE__ */ jsx("span", { children: displayTitle || "N/A" }),
|
|
29493
|
+
pinned && /* @__PURE__ */ jsx(IconPin, {}),
|
|
29232
29494
|
muted && /* @__PURE__ */ jsx(IconMute, {})
|
|
29233
29495
|
] }),
|
|
29234
29496
|
/* @__PURE__ */ jsxs("div", { className: "str-chat__channel-list-item-data__timestamp-and-badge", children: [
|
|
@@ -29247,7 +29509,8 @@ const UnMemoizedChannelListItemUI = (props) => {
|
|
|
29247
29509
|
] })
|
|
29248
29510
|
]
|
|
29249
29511
|
}
|
|
29250
|
-
)
|
|
29512
|
+
),
|
|
29513
|
+
/* @__PURE__ */ jsx(ChannelListItemActionButtons$1, {})
|
|
29251
29514
|
] });
|
|
29252
29515
|
};
|
|
29253
29516
|
const ChannelListItemUI = React.memo(
|
|
@@ -29350,6 +29613,7 @@ const ChannelListItem = (props) => {
|
|
|
29350
29613
|
const { displayImage, displayTitle, groupChannelDisplayInfo } = useChannelPreviewInfo({
|
|
29351
29614
|
channel
|
|
29352
29615
|
});
|
|
29616
|
+
const membership = useChannelMembershipState(channel);
|
|
29353
29617
|
const [lastMessage, setLastMessage] = useState(
|
|
29354
29618
|
channel.state.messages[channel.state.messages.length - 1]
|
|
29355
29619
|
);
|
|
@@ -29446,6 +29710,7 @@ const ChannelListItem = (props) => {
|
|
|
29446
29710
|
latestMessagePreview,
|
|
29447
29711
|
messageDeliveryStatus,
|
|
29448
29712
|
muted,
|
|
29713
|
+
pinned: !!membership.pinned_at,
|
|
29449
29714
|
setActiveChannel,
|
|
29450
29715
|
unread
|
|
29451
29716
|
}
|
|
@@ -29759,7 +30024,7 @@ const Notification = forwardRef(
|
|
|
29759
30024
|
}
|
|
29760
30025
|
removeNotification(notification.id);
|
|
29761
30026
|
};
|
|
29762
|
-
const
|
|
30027
|
+
const isPersistent2 = !notification.duration;
|
|
29763
30028
|
const severity = notification.severity;
|
|
29764
30029
|
const livePriority = severity === "error" ? "assertive" : "polite";
|
|
29765
30030
|
return /* @__PURE__ */ jsxs(
|
|
@@ -29805,7 +30070,7 @@ const Notification = forwardRef(
|
|
|
29805
30070
|
},
|
|
29806
30071
|
index
|
|
29807
30072
|
)) }),
|
|
29808
|
-
(showClose ||
|
|
30073
|
+
(showClose || isPersistent2) && /* @__PURE__ */ jsx(
|
|
29809
30074
|
Button,
|
|
29810
30075
|
{
|
|
29811
30076
|
appearance: "ghost",
|
|
@@ -29832,6 +30097,7 @@ const ENTER_TRANSLATION = {
|
|
|
29832
30097
|
top: { x: "0%", y: "-100%" }
|
|
29833
30098
|
};
|
|
29834
30099
|
const EXIT_ANIMATION_MS = 340;
|
|
30100
|
+
const DEFAULT_MIN_DISPLAY_MS = 1e3;
|
|
29835
30101
|
const isEnterFrom = (value) => value === "bottom" || value === "left" || value === "right" || value === "top";
|
|
29836
30102
|
const getNotificationEnterFrom = (notification, fallbackEnterFrom) => {
|
|
29837
30103
|
if (!notification) return fallbackEnterFrom;
|
|
@@ -29841,19 +30107,93 @@ const getNotificationEnterFrom = (notification, fallbackEnterFrom) => {
|
|
|
29841
30107
|
if (isEnterFrom(originEnterFrom)) return originEnterFrom;
|
|
29842
30108
|
return fallbackEnterFrom;
|
|
29843
30109
|
};
|
|
30110
|
+
const isPersistent = (notification) => !notification.duration;
|
|
30111
|
+
const haveSameType = (a, b) => !!a?.type && !!b?.type && a.type === b.type;
|
|
30112
|
+
const pickOldest = (notifications, displayed) => {
|
|
30113
|
+
const excludeId = displayed?.id ?? null;
|
|
30114
|
+
let oldest = null;
|
|
30115
|
+
for (const notification of notifications) {
|
|
30116
|
+
if (notification.id === excludeId) continue;
|
|
30117
|
+
if (!oldest || notification.createdAt < oldest.createdAt) {
|
|
30118
|
+
oldest = notification;
|
|
30119
|
+
}
|
|
30120
|
+
}
|
|
30121
|
+
return oldest;
|
|
30122
|
+
};
|
|
30123
|
+
const pickNewest = (notifications, displayed) => {
|
|
30124
|
+
const excludeId = displayed?.id ?? null;
|
|
30125
|
+
let newest = null;
|
|
30126
|
+
for (const notification of notifications) {
|
|
30127
|
+
if (notification.id === excludeId) continue;
|
|
30128
|
+
if (!newest || notification.createdAt > newest.createdAt) {
|
|
30129
|
+
newest = notification;
|
|
30130
|
+
}
|
|
30131
|
+
}
|
|
30132
|
+
return newest;
|
|
30133
|
+
};
|
|
30134
|
+
const pickNewestPersistent = (notifications, excludeId) => {
|
|
30135
|
+
let newest = null;
|
|
30136
|
+
for (const notification of notifications) {
|
|
30137
|
+
if (notification.id === excludeId) continue;
|
|
30138
|
+
if (!isPersistent(notification)) continue;
|
|
30139
|
+
if (!newest || notification.createdAt > newest.createdAt) {
|
|
30140
|
+
newest = notification;
|
|
30141
|
+
}
|
|
30142
|
+
}
|
|
30143
|
+
return newest;
|
|
30144
|
+
};
|
|
30145
|
+
const pickNewestOfType = (notifications, type, excludeId) => {
|
|
30146
|
+
if (!type) return null;
|
|
30147
|
+
let newest = null;
|
|
30148
|
+
for (const notification of notifications) {
|
|
30149
|
+
if (notification.id === excludeId) continue;
|
|
30150
|
+
if (notification.type !== type) continue;
|
|
30151
|
+
if (!newest || notification.createdAt > newest.createdAt) {
|
|
30152
|
+
newest = notification;
|
|
30153
|
+
}
|
|
30154
|
+
}
|
|
30155
|
+
return newest;
|
|
30156
|
+
};
|
|
30157
|
+
const createDefaultPickNext = (pickFromQueue = pickOldest) => (notifications, displayed) => {
|
|
30158
|
+
if (notifications.length === 0) return null;
|
|
30159
|
+
const newestPersistent = pickNewestPersistent(notifications, null);
|
|
30160
|
+
if (!displayed) {
|
|
30161
|
+
return newestPersistent ?? pickFromQueue(notifications, null);
|
|
30162
|
+
}
|
|
30163
|
+
const displayedInStore = notifications.some(({ id }) => id === displayed.id);
|
|
30164
|
+
if (!displayedInStore) {
|
|
30165
|
+
return newestPersistent ?? pickFromQueue(notifications, null);
|
|
30166
|
+
}
|
|
30167
|
+
if (isPersistent(displayed)) {
|
|
30168
|
+
const newerPersistent = newestPersistent && newestPersistent.id !== displayed.id ? newestPersistent : pickNewestPersistent(notifications, displayed.id);
|
|
30169
|
+
if (newerPersistent && newerPersistent.createdAt > displayed.createdAt) {
|
|
30170
|
+
return newerPersistent;
|
|
30171
|
+
}
|
|
30172
|
+
return displayed;
|
|
30173
|
+
}
|
|
30174
|
+
const sameTypeNewest = pickNewestOfType(notifications, displayed.type, displayed.id);
|
|
30175
|
+
if (sameTypeNewest) return sameTypeNewest;
|
|
30176
|
+
if (newestPersistent) return newestPersistent;
|
|
30177
|
+
return pickFromQueue(notifications, displayed) ?? displayed;
|
|
30178
|
+
};
|
|
30179
|
+
const defaultPickNext = createDefaultPickNext(pickOldest);
|
|
29844
30180
|
const NotificationList = ({
|
|
29845
30181
|
className,
|
|
29846
30182
|
enterFrom = "bottom",
|
|
29847
30183
|
fallbackPanel,
|
|
29848
30184
|
filter,
|
|
30185
|
+
minDisplayMs = DEFAULT_MIN_DISPLAY_MS,
|
|
29849
30186
|
panel,
|
|
30187
|
+
pickNext = defaultPickNext,
|
|
29850
30188
|
verticalAlignment = "bottom"
|
|
29851
30189
|
}) => {
|
|
29852
30190
|
const { Notification: NotificationComponent = Notification } = useComponentContext();
|
|
29853
30191
|
const { t } = useTranslationContext();
|
|
29854
30192
|
const { removeNotification, startNotificationTimeout } = useNotificationApi();
|
|
29855
30193
|
const exitTimeoutRef = useRef(null);
|
|
29856
|
-
const
|
|
30194
|
+
const replacementTimeoutRef = useRef(null);
|
|
30195
|
+
const candidateRef = useRef(null);
|
|
30196
|
+
const displayedAtRef = useRef(null);
|
|
29857
30197
|
const listRef = useRef(null);
|
|
29858
30198
|
const observedElementRef = useRef(null);
|
|
29859
30199
|
const startedTimeoutIdsRef = useRef(null);
|
|
@@ -29876,7 +30216,6 @@ const NotificationList = ({
|
|
|
29876
30216
|
filter: combinedFilter,
|
|
29877
30217
|
panel
|
|
29878
30218
|
});
|
|
29879
|
-
const nextNotification = notifications[0] ?? null;
|
|
29880
30219
|
const dismiss = useCallback(
|
|
29881
30220
|
(id) => {
|
|
29882
30221
|
startedTimeoutIdsRef.current?.delete(id);
|
|
@@ -29892,33 +30231,105 @@ const NotificationList = ({
|
|
|
29892
30231
|
}
|
|
29893
30232
|
});
|
|
29894
30233
|
}, [notifications]);
|
|
29895
|
-
|
|
29896
|
-
|
|
29897
|
-
|
|
30234
|
+
const clearReplacementTimeout = useCallback(() => {
|
|
30235
|
+
if (replacementTimeoutRef.current !== null) {
|
|
30236
|
+
window.clearTimeout(replacementTimeoutRef.current);
|
|
30237
|
+
replacementTimeoutRef.current = null;
|
|
30238
|
+
}
|
|
30239
|
+
}, []);
|
|
29898
30240
|
useEffect(
|
|
29899
30241
|
() => () => {
|
|
29900
|
-
|
|
30242
|
+
clearReplacementTimeout();
|
|
30243
|
+
if (exitTimeoutRef.current !== null) {
|
|
29901
30244
|
window.clearTimeout(exitTimeoutRef.current);
|
|
30245
|
+
exitTimeoutRef.current = null;
|
|
29902
30246
|
}
|
|
29903
30247
|
},
|
|
29904
|
-
[]
|
|
30248
|
+
[clearReplacementTimeout]
|
|
29905
30249
|
);
|
|
29906
30250
|
useEffect(() => {
|
|
30251
|
+
candidateRef.current = pickNext(notifications, displayedNotification);
|
|
30252
|
+
}, [displayedNotification, notifications, pickNext]);
|
|
30253
|
+
useEffect(() => {
|
|
30254
|
+
if (transitionState === "exit") return;
|
|
29907
30255
|
if (!displayedNotification) {
|
|
29908
|
-
|
|
29909
|
-
|
|
29910
|
-
|
|
30256
|
+
const candidate2 = pickNext(notifications, null);
|
|
30257
|
+
if (candidate2) {
|
|
30258
|
+
displayedAtRef.current = Date.now();
|
|
30259
|
+
setDisplayedNotification(candidate2);
|
|
30260
|
+
setTransitionState("enter");
|
|
30261
|
+
}
|
|
29911
30262
|
return;
|
|
29912
30263
|
}
|
|
29913
|
-
|
|
29914
|
-
if (
|
|
29915
|
-
|
|
29916
|
-
|
|
29917
|
-
|
|
29918
|
-
|
|
29919
|
-
|
|
29920
|
-
|
|
29921
|
-
|
|
30264
|
+
const candidate = pickNext(notifications, displayedNotification);
|
|
30265
|
+
if (!candidate) {
|
|
30266
|
+
clearReplacementTimeout();
|
|
30267
|
+
setTransitionState("exit");
|
|
30268
|
+
exitTimeoutRef.current = window.setTimeout(() => {
|
|
30269
|
+
exitTimeoutRef.current = null;
|
|
30270
|
+
displayedAtRef.current = null;
|
|
30271
|
+
setDisplayedNotification(null);
|
|
30272
|
+
setTransitionState("enter");
|
|
30273
|
+
}, EXIT_ANIMATION_MS);
|
|
30274
|
+
return;
|
|
30275
|
+
}
|
|
30276
|
+
if (candidate.id === displayedNotification.id) {
|
|
30277
|
+
clearReplacementTimeout();
|
|
30278
|
+
return;
|
|
30279
|
+
}
|
|
30280
|
+
const displayedInStore = notifications.some(
|
|
30281
|
+
({ id }) => id === displayedNotification.id
|
|
30282
|
+
);
|
|
30283
|
+
const startSwap = () => {
|
|
30284
|
+
replacementTimeoutRef.current = null;
|
|
30285
|
+
setTransitionState("exit");
|
|
30286
|
+
const previousId = displayedNotification.id;
|
|
30287
|
+
const wasInStore = displayedInStore;
|
|
30288
|
+
exitTimeoutRef.current = window.setTimeout(() => {
|
|
30289
|
+
exitTimeoutRef.current = null;
|
|
30290
|
+
if (wasInStore) {
|
|
30291
|
+
startedTimeoutIdsRef.current?.delete(previousId);
|
|
30292
|
+
removeNotification(previousId);
|
|
30293
|
+
}
|
|
30294
|
+
const next = candidateRef.current;
|
|
30295
|
+
if (next && next.id !== previousId) {
|
|
30296
|
+
displayedAtRef.current = Date.now();
|
|
30297
|
+
setDisplayedNotification(next);
|
|
30298
|
+
setTransitionState("enter");
|
|
30299
|
+
} else {
|
|
30300
|
+
displayedAtRef.current = null;
|
|
30301
|
+
setDisplayedNotification(null);
|
|
30302
|
+
setTransitionState("enter");
|
|
30303
|
+
}
|
|
30304
|
+
}, EXIT_ANIMATION_MS);
|
|
30305
|
+
};
|
|
30306
|
+
if (!displayedInStore) {
|
|
30307
|
+
clearReplacementTimeout();
|
|
30308
|
+
startSwap();
|
|
30309
|
+
return;
|
|
30310
|
+
}
|
|
30311
|
+
if (haveSameType(displayedNotification, candidate)) {
|
|
30312
|
+
clearReplacementTimeout();
|
|
30313
|
+
startSwap();
|
|
30314
|
+
return;
|
|
30315
|
+
}
|
|
30316
|
+
const elapsed = displayedAtRef.current ? Date.now() - displayedAtRef.current : 0;
|
|
30317
|
+
const remaining = Math.max(0, minDisplayMs - elapsed);
|
|
30318
|
+
if (remaining === 0) {
|
|
30319
|
+
clearReplacementTimeout();
|
|
30320
|
+
startSwap();
|
|
30321
|
+
} else if (replacementTimeoutRef.current === null) {
|
|
30322
|
+
replacementTimeoutRef.current = window.setTimeout(startSwap, remaining);
|
|
30323
|
+
}
|
|
30324
|
+
}, [
|
|
30325
|
+
clearReplacementTimeout,
|
|
30326
|
+
displayedNotification,
|
|
30327
|
+
minDisplayMs,
|
|
30328
|
+
notifications,
|
|
30329
|
+
pickNext,
|
|
30330
|
+
removeNotification,
|
|
30331
|
+
transitionState
|
|
30332
|
+
]);
|
|
29922
30333
|
const notification = displayedNotification;
|
|
29923
30334
|
const notificationEnterFrom = getNotificationEnterFrom(notification, enterFrom);
|
|
29924
30335
|
useEffect(() => {
|
|
@@ -30400,7 +30811,7 @@ const useChat = ({
|
|
|
30400
30811
|
};
|
|
30401
30812
|
useEffect(() => {
|
|
30402
30813
|
if (!client) return;
|
|
30403
|
-
const version = "14.
|
|
30814
|
+
const version = "14.3.0";
|
|
30404
30815
|
const userAgent = client.getUserAgent();
|
|
30405
30816
|
if (!userAgent.includes("stream-chat-react")) {
|
|
30406
30817
|
client.setUserAgent(`stream-chat-react-${version}-${userAgent}`);
|
|
@@ -31022,6 +31433,7 @@ export {
|
|
|
31022
31433
|
areMessagePropsEqual,
|
|
31023
31434
|
areMessageUIPropsEqual,
|
|
31024
31435
|
countEmojis,
|
|
31436
|
+
createDefaultPickNext,
|
|
31025
31437
|
bK as createIcon,
|
|
31026
31438
|
deTranslations,
|
|
31027
31439
|
defaultAllowedTagNames,
|
|
@@ -31052,6 +31464,7 @@ export {
|
|
|
31052
31464
|
getCssDimensionsVariables,
|
|
31053
31465
|
getGroupChannelDisplayInfo,
|
|
31054
31466
|
getGroupStyles,
|
|
31467
|
+
getHasExtendedReactions,
|
|
31055
31468
|
bS as getImages,
|
|
31056
31469
|
getIsFirstUnreadMessage,
|
|
31057
31470
|
getLastReceived,
|
|
@@ -31119,6 +31532,8 @@ export {
|
|
|
31119
31532
|
modalDialogManagerId,
|
|
31120
31533
|
moveChannelUpwards,
|
|
31121
31534
|
nlTranslations,
|
|
31535
|
+
pickNewest,
|
|
31536
|
+
pickOldest,
|
|
31122
31537
|
plusPlusToEmphasis,
|
|
31123
31538
|
processMessages,
|
|
31124
31539
|
ptTranslations,
|
|
@@ -31128,6 +31543,7 @@ export {
|
|
|
31128
31543
|
renderText,
|
|
31129
31544
|
resampleWaveformData,
|
|
31130
31545
|
ruTranslations,
|
|
31546
|
+
shouldBackspaceExitCommandMode,
|
|
31131
31547
|
shouldConsiderArchivedChannels,
|
|
31132
31548
|
shouldConsiderPinnedChannels,
|
|
31133
31549
|
toBaseImageDescriptors,
|
|
@@ -31182,6 +31598,7 @@ export {
|
|
|
31182
31598
|
useMentionsHandler,
|
|
31183
31599
|
useMessageBounceContext,
|
|
31184
31600
|
useMessageComposerBindings,
|
|
31601
|
+
useMessageComposerCommands,
|
|
31185
31602
|
useMessageComposerContext,
|
|
31186
31603
|
useMessageComposerController,
|
|
31187
31604
|
useMessageComposerHasSendableData,
|