@azure/communication-react 1.5.1-alpha-202304040013 → 1.5.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.beta.md +76 -1
- package/CHANGELOG.json +621 -0
- package/dist/communication-react.d.ts +160 -192
- package/dist/dist-cjs/communication-react/index.js +1615 -2195
- package/dist/dist-cjs/communication-react/index.js.map +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js +1 -1
- package/dist/dist-esm/acs-ui-common/src/telemetryVersion.js.map +1 -1
- package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js +2 -29
- package/dist/dist-esm/chat-component-bindings/src/messageThreadSelector.js.map +1 -1
- package/dist/dist-esm/chat-component-bindings/src/utils/constants.d.ts +0 -4
- package/dist/dist-esm/chat-component-bindings/src/utils/constants.js +0 -4
- package/dist/dist-esm/chat-component-bindings/src/utils/constants.js.map +1 -1
- package/dist/dist-esm/chat-component-bindings/src/utils/updateMessagesWithAttached.js +26 -32
- package/dist/dist-esm/chat-component-bindings/src/utils/updateMessagesWithAttached.js.map +1 -1
- package/dist/dist-esm/chat-stateful-client/src/convertChatMessage.js +1 -6
- package/dist/dist-esm/chat-stateful-client/src/convertChatMessage.js.map +1 -1
- package/dist/dist-esm/chat-stateful-client/src/types/ChatMessageWithStatus.d.ts +0 -1
- package/dist/dist-esm/chat-stateful-client/src/types/ChatMessageWithStatus.js.map +1 -1
- package/dist/dist-esm/communication-react/src/index.d.ts +0 -2
- package/dist/dist-esm/communication-react/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/CaptionsBanner.js +29 -31
- package/dist/dist-esm/react-components/src/components/CaptionsBanner.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponent.d.ts +1 -2
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponent.js +13 -11
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.d.ts +1 -2
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.js +20 -34
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.d.ts +2 -11
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js +9 -47
- package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageContent.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.d.ts +0 -7
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.js +1 -5
- package/dist/dist-esm/react-components/src/components/FileDownloadCards.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/MessageThread.d.ts +3 -10
- package/dist/dist-esm/react-components/src/components/MessageThread.js +36 -57
- package/dist/dist-esm/react-components/src/components/MessageThread.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/index.d.ts +0 -1
- package/dist/dist-esm/react-components/src/components/index.js +0 -1
- package/dist/dist-esm/react-components/src/components/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/styles/CaptionsBanner.style.d.ts +13 -0
- package/dist/dist-esm/react-components/src/components/styles/CaptionsBanner.style.js +35 -0
- package/dist/dist-esm/react-components/src/components/styles/CaptionsBanner.style.js.map +1 -0
- package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.d.ts +0 -5
- package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js +0 -28
- package/dist/dist-esm/react-components/src/components/styles/MessageThread.styles.js.map +1 -1
- package/dist/dist-esm/react-components/src/components/utils/getParticipantsWhoHaveReadMessage.d.ts +4 -6
- package/dist/dist-esm/react-components/src/components/utils/getParticipantsWhoHaveReadMessage.js +1 -1
- package/dist/dist-esm/react-components/src/components/utils/getParticipantsWhoHaveReadMessage.js.map +1 -1
- package/dist/dist-esm/react-components/src/index.d.ts +0 -1
- package/dist/dist-esm/react-components/src/index.js.map +1 -1
- package/dist/dist-esm/react-components/src/localization/locales/de-DE/strings.json +116 -11
- package/dist/dist-esm/react-components/src/localization/locales/en-GB/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/en-US/strings.json +1 -3
- package/dist/dist-esm/react-components/src/localization/locales/es-ES/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/fr-FR/strings.json +116 -11
- package/dist/dist-esm/react-components/src/localization/locales/it-IT/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/ja-JP/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/ko-KR/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/nl-NL/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/pt-BR/strings.json +116 -11
- package/dist/dist-esm/react-components/src/localization/locales/ru-RU/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/tr-TR/strings.json +116 -11
- package/dist/dist-esm/react-components/src/localization/locales/zh-CN/strings.json +115 -10
- package/dist/dist-esm/react-components/src/localization/locales/zh-TW/strings.json +115 -10
- package/dist/dist-esm/react-components/src/theming/icons.d.ts +0 -1
- package/dist/dist-esm/react-components/src/theming/icons.js +0 -8
- package/dist/dist-esm/react-components/src/theming/icons.js.map +1 -1
- package/dist/dist-esm/react-components/src/types/ChatMessage.d.ts +1 -20
- package/dist/dist-esm/react-components/src/types/ChatMessage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.d.ts +0 -20
- package/dist/dist-esm/react-composites/src/composites/CallComposite/Strings.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.d.ts +1 -7
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js +2 -14
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/AzureCommunicationCallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.d.ts +0 -8
- package/dist/dist-esm/react-composites/src/composites/CallComposite/adapter/CallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js +20 -93
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/CallArrangement.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Camera.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Camera.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Custom.d.ts +3 -9
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Custom.js +1 -3
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Custom.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Devices.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Devices.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/EndCall.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/EndCall.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Microphone.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Microphone.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Participants.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/Participants.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/ScreenShare.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/components/buttons/ScreenShare.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/index.d.ts +2 -2
- package/dist/dist-esm/react-composites/src/composites/CallComposite/index.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/ConfigurationPage.js +1 -19
- package/dist/dist-esm/react-composites/src/composites/CallComposite/pages/ConfigurationPage.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.d.ts +1 -5
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.js +0 -20
- package/dist/dist-esm/react-composites/src/composites/CallComposite/styles/CallConfiguration.styles.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/types/CallControlOptions.d.ts +87 -5
- package/dist/dist-esm/react-composites/src/composites/CallComposite/types/CallControlOptions.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallComposite/utils/Utils.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.d.ts +75 -15
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js +5 -7
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatComposite.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.d.ts +28 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.js +194 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CallWithChatControlBar.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/{common/ControlBar → CallWithChatComposite}/CustomButton.d.ts +16 -19
- package/dist/dist-esm/react-composites/src/composites/{common/ControlBar → CallWithChatComposite}/CustomButton.js +4 -4
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/CustomButton.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/{common/ControlBar → CallWithChatComposite}/PeopleButton.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/{common/ControlBar → CallWithChatComposite}/PeopleButton.js +3 -3
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/PeopleButton.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/{common/Drawer → CallWithChatComposite}/PreparedMoreDrawer.d.ts +2 -2
- package/dist/dist-esm/react-composites/src/composites/{common/Drawer → CallWithChatComposite}/PreparedMoreDrawer.js +5 -5
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/PreparedMoreDrawer.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.d.ts +0 -2
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js +1 -7
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/AzureCommunicationCallWithChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.d.ts +0 -10
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedCallAdapter.d.ts +0 -2
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedCallAdapter.js +1 -7
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/adapter/CallWithChatBackedCallAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/{common/ControlBar → CallWithChatComposite/components}/DesktopMoreButton.d.ts +2 -2
- package/dist/dist-esm/react-composites/src/composites/{common/ControlBar → CallWithChatComposite/components}/DesktopMoreButton.js +3 -3
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/DesktopMoreButton.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/{common/Drawer → CallWithChatComposite/components}/MoreDrawer.d.ts +2 -2
- package/dist/dist-esm/react-composites/src/composites/{common/Drawer → CallWithChatComposite/components}/MoreDrawer.js +5 -4
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/components/MoreDrawer.js.map +1 -0
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/index.d.ts +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/index.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/state/CallWithChatAdapterState.d.ts +0 -3
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/state/CallWithChatAdapterState.js +2 -6
- package/dist/dist-esm/react-composites/src/composites/CallWithChatComposite/state/CallWithChatAdapterState.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.d.ts +0 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js +0 -11
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationChatAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationFileUploadAdapter.d.ts +1 -4
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationFileUploadAdapter.js +1 -29
- package/dist/dist-esm/react-composites/src/composites/ChatComposite/adapter/AzureCommunicationFileUploadAdapter.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/VideoEffectsPane.d.ts +0 -2
- package/dist/dist-esm/react-composites/src/composites/common/VideoEffectsPane.js +3 -88
- package/dist/dist-esm/react-composites/src/composites/common/VideoEffectsPane.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/common/icons.d.ts +1 -7
- package/dist/dist-esm/react-composites/src/composites/common/icons.js +1 -7
- package/dist/dist-esm/react-composites/src/composites/common/icons.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/index.d.ts +0 -3
- package/dist/dist-esm/react-composites/src/composites/index.js.map +1 -1
- package/dist/dist-esm/react-composites/src/composites/localization/locales/de-DE/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/en-GB/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/en-US/strings.json +0 -5
- package/dist/dist-esm/react-composites/src/composites/localization/locales/es-ES/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/fr-FR/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/it-IT/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/ja-JP/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/ko-KR/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/nl-NL/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/pt-BR/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/ru-RU/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/tr-TR/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/zh-CN/strings.json +17 -3
- package/dist/dist-esm/react-composites/src/composites/localization/locales/zh-TW/strings.json +17 -3
- package/package.json +10 -10
- package/dist/dist-esm/react-components/src/components/Caption.d.ts +0 -21
- package/dist/dist-esm/react-components/src/components/Caption.js +0 -32
- package/dist/dist-esm/react-components/src/components/Caption.js.map +0 -1
- package/dist/dist-esm/react-components/src/components/styles/Captions.style.d.ts +0 -21
- package/dist/dist-esm/react-components/src/components/styles/Captions.style.js +0 -41
- package/dist/dist-esm/react-components/src/components/styles/Captions.style.js.map +0 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.d.ts +0 -30
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js +0 -253
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CommonCallControlBar.js.map +0 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/CustomButton.js.map +0 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/DesktopMoreButton.js.map +0 -1
- package/dist/dist-esm/react-composites/src/composites/common/ControlBar/PeopleButton.js.map +0 -1
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/MoreDrawer.js.map +0 -1
- package/dist/dist-esm/react-composites/src/composites/common/Drawer/PreparedMoreDrawer.js.map +0 -1
- package/dist/dist-esm/react-composites/src/composites/common/types/CommonCallControlOptions.d.ts +0 -165
- package/dist/dist-esm/react-composites/src/composites/common/types/CommonCallControlOptions.js +0 -4
- package/dist/dist-esm/react-composites/src/composites/common/types/CommonCallControlOptions.js.map +0 -1
package/dist/dist-esm/react-components/src/components/ChatMessage/ChatMessageComponent.js.map
CHANGED
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ChatMessageComponent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponent.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;;;;;;;;;AAIlC,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;
|
1
|
+
{"version":3,"file":"ChatMessageComponent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponent.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;;;;;;;;;;AAIlC,OAAO,KAAK,EAAE,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,6BAA6B,EAAE,MAAM,iCAAiC,CAAC;AAGhF,OAAO,EAAE,mCAAmC,EAAE,MAAM,uCAAuC,CAAC;AAiE5F;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,KAAgC,EAAe,EAAE;IACpF,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAElD,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAE1E,MAAM,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;IAC1D,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;QACrC,IAAI,eAAe,IAAI,OAAO,CAAC,SAAS,EAAE;YACxC,eAAe,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;SACpC;QACD,4FAA4F;aACvF,IAAI,eAAe,IAAI,OAAO,CAAC,eAAe,EAAE;YACnD,eAAe,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;SAC1C;IACH,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC,CAAC;IAClE,MAAM,aAAa,GAAG,WAAW,CAAC,GAAG,EAAE;;QACrC,eAAe,IAAI,OAAO,CAAC,eAAe,IAAI,eAAe,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QACvF,aAAa,IAAI,aAAa,CAAC,MAAA,OAAO,CAAC,OAAO,mCAAI,EAAE,CAAC,CAAC;IACxD,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,EAAE,OAAO,CAAC,OAAO,EAAE,aAAa,EAAE,eAAe,CAAC,CAAC,CAAC;IAE/E,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,KAAK,MAAM,EAAE;QACxC,OAAO,yCAAK,CAAC;KACd;SAAM,IAAI,SAAS,EAAE;QACpB,OAAO,CACL,oBAAC,6BAA6B,IAC5B,OAAO,EAAE,OAAO,EAChB,iBAAiB,EAAE,KAAK,CAAC,6BAA6B,EACtD,OAAO,EAAE,KAAK,CAAC,OAAO,EACtB,QAAQ,EAAE,CAAO,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,EAAE;gBAC1C,KAAK,CAAC,eAAe;oBACnB,KAAK,CAAC,OAAO,CAAC,SAAS;oBACvB,CAAC,MAAM,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;gBAClF,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC,CAAA,EACD,QAAQ,EAAE,GAAG,EAAE;gBACb,YAAY,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC,GACD,CACH,CAAC;KACH;SAAM;QACL,OAAO,CACL,oBAAC,mCAAmC,oBAC9B,KAAK,IACT,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,WAAW,EACxB,aAAa,EAAE,aAAa,EAC5B,cAAc,EAAE,KAAK,CAAC,cAAc;YACpC,0DAA0D;YAC1D,uBAAuB,EAAE,KAAK,CAAC,uBAAuB,EACtD,OAAO,EAAE,KAAK,CAAC,OAAO,IACtB,CACH,CAAC;KACH;AACH,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { ComponentSlotStyle } from '@fluentui/react-northstar';\nimport { _formatString } from '@internal/acs-ui-common';\nimport React, { useCallback, useState } from 'react';\nimport { ChatMessageComponentAsEditBox } from './ChatMessageComponentAsEditBox';\nimport { MessageThreadStrings } from '../MessageThread';\nimport { ChatMessage, OnRenderAvatarCallback } from '../../types';\nimport { ChatMessageComponentAsMessageBubble } from './ChatMessageComponentAsMessageBubble';\nimport { FileDownloadHandler, FileMetadata } from '../FileDownloadCards';\n\ntype ChatMessageComponentProps = {\n message: ChatMessage;\n userId: string;\n messageContainerStyle?: ComponentSlotStyle;\n showDate?: boolean;\n disableEditing?: boolean;\n onUpdateMessage?: (\n messageId: string,\n content: string,\n metadata?: Record<string, string>,\n options?: {\n attachedFilesMetadata?: FileMetadata[];\n }\n ) => Promise<void>;\n /**\n * Callback to delete a message. Also called before resending a message that failed to send.\n * @param messageId ID of the message to delete\n */\n onDeleteMessage?: (messageId: string) => Promise<void>;\n /**\n * Callback to send a message\n * @param content The message content to send\n */\n onSendMessage?: (content: string) => Promise<void>;\n strings: MessageThreadStrings;\n messageStatus?: string;\n /**\n * Whether the status indicator for each message is displayed or not.\n */\n showMessageStatus?: boolean;\n /**\n * Inline the accept and reject edit buttons when editing a message.\n * Setting to false will mean they are on a new line inside the editable chat message.\n */\n inlineAcceptRejectEditButtons: boolean;\n /**\n * Optional callback to render uploaded files in the message component.\n */\n onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /**\n * Optional function called when someone clicks on the file download icon.\n */\n fileDownloadHandler?: FileDownloadHandler;\n remoteParticipantsCount?: number;\n onActionButtonClick: (\n message: ChatMessage,\n setMessageReadBy: (readBy: { id: string; displayName: string }[]) => void\n ) => void;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n\n /**\n * Optional function to provide customized date format.\n * @beta\n */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n};\n\n/**\n * @private\n */\nexport const ChatMessageComponent = (props: ChatMessageComponentProps): JSX.Element => {\n const [isEditing, setIsEditing] = useState(false);\n\n const onEditClick = useCallback(() => setIsEditing(true), [setIsEditing]);\n\n const { onDeleteMessage, onSendMessage, message } = props;\n const onRemoveClick = useCallback(() => {\n if (onDeleteMessage && message.messageId) {\n onDeleteMessage(message.messageId);\n }\n // when fail to send, message does not have message id, delete message using clientmessageid\n else if (onDeleteMessage && message.clientMessageId) {\n onDeleteMessage(message.clientMessageId);\n }\n }, [message.messageId, message.clientMessageId, onDeleteMessage]);\n const onResendClick = useCallback(() => {\n onDeleteMessage && message.clientMessageId && onDeleteMessage(message.clientMessageId);\n onSendMessage && onSendMessage(message.content ?? '');\n }, [message.clientMessageId, message.content, onSendMessage, onDeleteMessage]);\n\n if (props.message.messageType !== 'chat') {\n return <></>;\n } else if (isEditing) {\n return (\n <ChatMessageComponentAsEditBox\n message={message}\n inlineEditButtons={props.inlineAcceptRejectEditButtons}\n strings={props.strings}\n onSubmit={async (text, metadata, options) => {\n props.onUpdateMessage &&\n props.message.messageId &&\n (await props.onUpdateMessage(props.message.messageId, text, metadata, options));\n setIsEditing(false);\n }}\n onCancel={() => {\n setIsEditing(false);\n }}\n />\n );\n } else {\n return (\n <ChatMessageComponentAsMessageBubble\n {...props}\n onRemoveClick={onRemoveClick}\n onEditClick={onEditClick}\n onResendClick={onResendClick}\n onRenderAvatar={props.onRenderAvatar}\n /* @conditional-compile-remove(date-time-customization) */\n onDisplayDateTimeString={props.onDisplayDateTimeString}\n strings={props.strings}\n />\n );\n }\n};\n\"../../../../acs-ui-common/src\""]}
|
@@ -1,12 +1,11 @@
|
|
1
1
|
import { ComponentSlotStyle } from '@fluentui/react-northstar';
|
2
2
|
import React from 'react';
|
3
3
|
import { ChatMessage } from '../../types/ChatMessage';
|
4
|
-
import { BlockedMessage } from '../../types/ChatMessage';
|
5
4
|
import { MessageThreadStrings } from '../MessageThread';
|
6
5
|
import { OnRenderAvatarCallback } from '../../types';
|
7
6
|
import { FileDownloadHandler } from '../FileDownloadCards';
|
8
7
|
declare type ChatMessageComponentAsMessageBubbleProps = {
|
9
|
-
message: ChatMessage
|
8
|
+
message: ChatMessage;
|
10
9
|
messageContainerStyle?: ComponentSlotStyle;
|
11
10
|
showDate?: boolean;
|
12
11
|
disableEditing?: boolean;
|
@@ -2,6 +2,7 @@
|
|
2
2
|
// Licensed under the MIT license.
|
3
3
|
import { mergeStyles } from '@fluentui/react';
|
4
4
|
import { Chat, Text } from '@fluentui/react-northstar';
|
5
|
+
import { _formatString } from "../../../../acs-ui-common/src";
|
5
6
|
import React, { useCallback, useRef, useState } from 'react';
|
6
7
|
import { chatMessageEditedTagStyle, chatMessageDateStyle, chatMessageFailedTagStyle } from '../styles/ChatMessageComponent.styles';
|
7
8
|
import { formatTimeForChatMessage, formatTimestampForChatMessage } from '../utils/Datetime';
|
@@ -9,8 +10,6 @@ import { useIdentifiers } from '../../identifiers/IdentifierProvider';
|
|
9
10
|
import { useTheme } from '../../theming';
|
10
11
|
import { ChatMessageActionFlyout } from './ChatMessageActionsFlyout';
|
11
12
|
import { ChatMessageContent } from './ChatMessageContent';
|
12
|
-
/* @conditional-compile-remove(data-loss-prevention) */
|
13
|
-
import { BlockedMessageContent } from './ChatMessageContent';
|
14
13
|
import { chatMessageActionMenuProps } from './ChatMessageActionMenu';
|
15
14
|
import { _FileDownloadCards } from '../FileDownloadCards';
|
16
15
|
import { useLocale } from '../../localization';
|
@@ -50,10 +49,7 @@ const MessageBubble = (props) => {
|
|
50
49
|
const messageRef = useRef(null);
|
51
50
|
const messageActionButtonRef = useRef(null);
|
52
51
|
const [chatMessageActionFlyoutTarget, setChatMessageActionFlyoutTarget] = useState(undefined);
|
53
|
-
const chatActionsEnabled = !disableEditing &&
|
54
|
-
message.status !== 'sending' &&
|
55
|
-
!!message.mine &&
|
56
|
-
/* @conditional-compile-remove(data-loss-prevention) */ message.messageType !== 'blocked';
|
52
|
+
const chatActionsEnabled = !disableEditing && message.status !== 'sending' && !!message.mine;
|
57
53
|
const [messageReadBy, setMessageReadBy] = useState([]);
|
58
54
|
const actionMenuProps = wasInteractionByTouch
|
59
55
|
? undefined
|
@@ -64,10 +60,8 @@ const MessageBubble = (props) => {
|
|
64
60
|
// Force show the action button while the flyout is open (otherwise this will dismiss when the pointer is hovered over the flyout)
|
65
61
|
forceShow: chatMessageActionFlyoutTarget === messageActionButtonRef,
|
66
62
|
onActionButtonClick: () => {
|
67
|
-
|
68
|
-
|
69
|
-
setChatMessageActionFlyoutTarget(messageActionButtonRef);
|
70
|
-
}
|
63
|
+
props.onActionButtonClick(message, setMessageReadBy);
|
64
|
+
setChatMessageActionFlyoutTarget(messageActionButtonRef);
|
71
65
|
},
|
72
66
|
theme
|
73
67
|
});
|
@@ -90,29 +84,23 @@ const MessageBubble = (props) => {
|
|
90
84
|
locale,
|
91
85
|
fileDownloadHandler
|
92
86
|
]);
|
93
|
-
const
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
const getContent = useCallback(() => {
|
104
|
-
/* @conditional-compile-remove(data-loss-prevention) */
|
105
|
-
if (message.messageType === 'blocked') {
|
106
|
-
return (React.createElement("div", { tabIndex: 0 },
|
107
|
-
React.createElement(BlockedMessageContent, { message: message, strings: strings })));
|
108
|
-
}
|
109
|
-
return (React.createElement("div", { tabIndex: 0 },
|
110
|
-
React.createElement(ChatMessageContent, { message: message, strings: strings }),
|
111
|
-
props.onRenderFileDownloads ? props.onRenderFileDownloads(userId, message) : defaultOnRenderFileDownloads()));
|
112
|
-
}, [defaultOnRenderFileDownloads, message, props, strings, userId]);
|
87
|
+
const messageContentAriaText = props.message.content
|
88
|
+
? props.message.mine
|
89
|
+
? _formatString(strings.messageContentMineAriaText, {
|
90
|
+
message: props.message.content
|
91
|
+
})
|
92
|
+
: _formatString(strings.messageContentAriaText, {
|
93
|
+
author: `${props.message.senderDisplayName}`,
|
94
|
+
message: props.message.content
|
95
|
+
})
|
96
|
+
: undefined;
|
113
97
|
const chatMessage = (React.createElement(React.Fragment, null,
|
114
98
|
React.createElement("div", { ref: messageRef },
|
115
|
-
React.createElement(Chat.Message, { "data-ui-id": "chat-composite-message", className: mergeStyles(messageContainerStyle), styles: messageContainerStyle, content:
|
99
|
+
React.createElement(Chat.Message, { "data-ui-id": "chat-composite-message", className: mergeStyles(messageContainerStyle), styles: messageContainerStyle, content: React.createElement("div", { tabIndex: 0 },
|
100
|
+
React.createElement(ChatMessageContent, { message: message, liveAuthorIntro: strings.liveAuthorIntro, messageContentAriaText: messageContentAriaText }),
|
101
|
+
props.onRenderFileDownloads
|
102
|
+
? props.onRenderFileDownloads(userId, message)
|
103
|
+
: defaultOnRenderFileDownloads()), author: React.createElement(Text, { className: chatMessageDateStyle }, message.senderDisplayName), mine: message.mine, timestamp: React.createElement(Text, { "data-ui-id": ids.messageTimestamp }, formattedTimestamp), details: messageStatus === 'failed' ? (React.createElement("div", { className: chatMessageFailedTagStyle(theme) }, strings.failToSendTag)) : message.editedOn ? (React.createElement("div", { className: chatMessageEditedTagStyle(theme) }, strings.editedTag)) : undefined, positionActionMenu: false, actionMenu: actionMenuProps, onTouchStart: () => setWasInteractionByTouch(true), onPointerDown: () => setWasInteractionByTouch(false), onKeyDown: () => setWasInteractionByTouch(false), onBlur: () => setWasInteractionByTouch(false), onClick: () => {
|
116
104
|
if (!wasInteractionByTouch) {
|
117
105
|
return;
|
118
106
|
}
|
@@ -122,9 +110,7 @@ const MessageBubble = (props) => {
|
|
122
110
|
// In doing so here we set the target of the flyout to be the message and
|
123
111
|
// not the 3-dot menu button to position the flyout correctly.
|
124
112
|
setChatMessageActionFlyoutTarget(messageRef);
|
125
|
-
|
126
|
-
props.onActionButtonClick(message, setMessageReadBy);
|
127
|
-
}
|
113
|
+
props.onActionButtonClick(message, setMessageReadBy);
|
128
114
|
} })),
|
129
115
|
chatActionsEnabled && (React.createElement(ChatMessageActionFlyout, { hidden: !chatMessageActionFlyoutTarget, target: chatMessageActionFlyoutTarget, increaseFlyoutItemSize: wasInteractionByTouch, onDismiss: onActionFlyoutDismiss, onEditClick: onEditClick, onRemoveClick: onRemoveClick, onResendClick: onResendClick, strings: strings, messageReadBy: messageReadBy, messageStatus: messageStatus !== null && messageStatus !== void 0 ? messageStatus : 'failed', remoteParticipantsCount: remoteParticipantsCount, onRenderAvatar: onRenderAvatar, showMessageStatus: showMessageStatus }))));
|
130
116
|
return chatMessage;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ChatMessageComponentAsMessageBubble.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { IStyle, mergeStyles } from '@fluentui/react';\nimport { Chat, Text, ComponentSlotStyle } from '@fluentui/react-northstar';\nimport { _formatString } from '@internal/acs-ui-common';\nimport React, { useCallback, useRef, useState } from 'react';\nimport {\n chatMessageEditedTagStyle,\n chatMessageDateStyle,\n chatMessageFailedTagStyle\n} from '../styles/ChatMessageComponent.styles';\nimport { formatTimeForChatMessage, formatTimestampForChatMessage } from '../utils/Datetime';\nimport { useIdentifiers } from '../../identifiers/IdentifierProvider';\nimport { useTheme } from '../../theming';\nimport { ChatMessageActionFlyout } from './ChatMessageActionsFlyout';\nimport { ChatMessageContent } from './ChatMessageContent';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessageContent } from './ChatMessageContent';\nimport { ChatMessage } from '../../types/ChatMessage';\n/* @conditional-compile-remove(data-loss-prevention) */\nimport { BlockedMessage } from '../../types/ChatMessage';\nimport { MessageThreadStrings } from '../MessageThread';\nimport { chatMessageActionMenuProps } from './ChatMessageActionMenu';\nimport { OnRenderAvatarCallback } from '../../types';\nimport { _FileDownloadCards, FileDownloadHandler } from '../FileDownloadCards';\nimport { ComponentLocale, useLocale } from '../../localization';\n\ntype ChatMessageComponentAsMessageBubbleProps = {\n message: ChatMessage | /* @conditional-compile-remove(data-loss-prevention) */ BlockedMessage;\n messageContainerStyle?: ComponentSlotStyle;\n showDate?: boolean;\n disableEditing?: boolean;\n onEditClick: () => void;\n onRemoveClick?: () => void;\n onResendClick?: () => void;\n strings: MessageThreadStrings;\n userId: string;\n messageStatus?: string;\n /**\n * Whether the status indicator for each message is displayed or not.\n */\n showMessageStatus?: boolean;\n /**\n * Optional callback to render uploaded files in the message component.\n */\n onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /**\n * Optional function called when someone clicks on the file download icon.\n */\n fileDownloadHandler?: FileDownloadHandler;\n remoteParticipantsCount?: number;\n onActionButtonClick: (\n message: ChatMessage,\n setMessageReadBy: (readBy: { id: string; displayName: string }[]) => void\n ) => void;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n\n /**\n * Optional function to provide customized date format.\n * @beta\n */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n};\n\nconst generateDefaultTimestamp = (\n createdOn: Date,\n showDate: boolean | undefined,\n strings: MessageThreadStrings\n): string => {\n const formattedTimestamp = showDate\n ? formatTimestampForChatMessage(createdOn, new Date(), strings)\n : formatTimeForChatMessage(createdOn);\n\n return formattedTimestamp;\n};\n\n// onDisplayDateTimeString from props overwrite onDisplayDateTimeString from locale\nconst generateCustomizedTimestamp = (\n props: ChatMessageComponentAsMessageBubbleProps,\n createdOn: Date,\n locale: ComponentLocale\n): string => {\n /* @conditional-compile-remove(date-time-customization) */\n return props.onDisplayDateTimeString\n ? props.onDisplayDateTimeString(createdOn)\n : locale.onDisplayDateTimeString\n ? locale.onDisplayDateTimeString(createdOn)\n : '';\n\n return '';\n};\n/** @private */\nconst MessageBubble = (props: ChatMessageComponentAsMessageBubbleProps): JSX.Element => {\n const ids = useIdentifiers();\n const theme = useTheme();\n const locale = useLocale();\n\n const {\n userId,\n message,\n onRemoveClick,\n onResendClick,\n disableEditing,\n showDate,\n messageContainerStyle,\n strings,\n onEditClick,\n remoteParticipantsCount = 0,\n onRenderAvatar,\n showMessageStatus,\n messageStatus,\n fileDownloadHandler\n } = props;\n\n const defaultTimeStamp = message.createdOn\n ? generateDefaultTimestamp(message.createdOn, showDate, strings)\n : undefined;\n\n const customTimestamp = message.createdOn ? generateCustomizedTimestamp(props, message.createdOn, locale) : '';\n\n const formattedTimestamp = customTimestamp || defaultTimeStamp;\n\n // Track if the action menu was opened by touch - if so we increase the touch targets for the items\n const [wasInteractionByTouch, setWasInteractionByTouch] = useState(false);\n\n // The chat message action flyout should target the Chat.Message action menu if clicked,\n // or target the chat message if opened via touch press.\n // Undefined indicates the flyout menu should not be being shown.\n const messageRef = useRef<HTMLDivElement | null>(null);\n const messageActionButtonRef = useRef<HTMLElement | null>(null);\n const [chatMessageActionFlyoutTarget, setChatMessageActionFlyoutTarget] = useState<\n React.MutableRefObject<HTMLElement | null> | undefined\n >(undefined);\n\n const chatActionsEnabled =\n !disableEditing &&\n message.status !== 'sending' &&\n !!message.mine &&\n /* @conditional-compile-remove(data-loss-prevention) */ message.messageType !== 'blocked';\n const [messageReadBy, setMessageReadBy] = useState<{ id: string; displayName: string }[]>([]);\n\n const actionMenuProps = wasInteractionByTouch\n ? undefined\n : chatMessageActionMenuProps({\n ariaLabel: strings.actionMenuMoreOptions ?? '',\n enabled: chatActionsEnabled,\n menuButtonRef: messageActionButtonRef,\n // Force show the action button while the flyout is open (otherwise this will dismiss when the pointer is hovered over the flyout)\n forceShow: chatMessageActionFlyoutTarget === messageActionButtonRef,\n onActionButtonClick: () => {\n if (message.messageType === 'chat') {\n props.onActionButtonClick(message, setMessageReadBy);\n setChatMessageActionFlyoutTarget(messageActionButtonRef);\n }\n },\n theme\n });\n\n const onActionFlyoutDismiss = useCallback((): void => {\n // When the flyout dismiss is called, since we control if the action flyout is visible\n // or not we need to set the target to undefined here to actually hide the action flyout\n setChatMessageActionFlyoutTarget(undefined);\n }, [setChatMessageActionFlyoutTarget]);\n\n const defaultOnRenderFileDownloads = useCallback(\n () => (\n <_FileDownloadCards\n userId={userId}\n fileMetadata={message['attachedFilesMetadata'] || []}\n downloadHandler={fileDownloadHandler}\n /* @conditional-compile-remove(file-sharing) */\n strings={{ downloadFile: props.strings.downloadFile ?? locale.strings.messageThread.downloadFile }}\n />\n ),\n [\n userId,\n message,\n /* @conditional-compile-remove(file-sharing) */\n props,\n /* @conditional-compile-remove(file-sharing) */\n locale,\n fileDownloadHandler\n ]\n );\n\n const editedOn = 'editedOn' in message ? message.editedOn : undefined;\n const getMessageDetails = useCallback(() => {\n if (messageStatus === 'failed') {\n return <div className={chatMessageFailedTagStyle(theme)}>{strings.failToSendTag}</div>;\n } else if (message.messageType === 'chat' && editedOn) {\n return <div className={chatMessageEditedTagStyle(theme)}>{strings.editedTag}</div>;\n }\n return undefined;\n }, [editedOn, message.messageType, messageStatus, strings.editedTag, strings.failToSendTag, theme]);\n\n const getContent = useCallback(() => {\n /* @conditional-compile-remove(data-loss-prevention) */\n if (message.messageType === 'blocked') {\n return (\n <div tabIndex={0}>\n <BlockedMessageContent message={message} strings={strings} />\n </div>\n );\n }\n return (\n <div tabIndex={0}>\n <ChatMessageContent message={message} strings={strings} />\n {props.onRenderFileDownloads ? props.onRenderFileDownloads(userId, message) : defaultOnRenderFileDownloads()}\n </div>\n );\n }, [defaultOnRenderFileDownloads, message, props, strings, userId]);\n\n const chatMessage = (\n <>\n <div ref={messageRef}>\n <Chat.Message\n data-ui-id=\"chat-composite-message\"\n className={mergeStyles(messageContainerStyle as IStyle)}\n styles={messageContainerStyle}\n content={getContent()}\n author={<Text className={chatMessageDateStyle}>{message.senderDisplayName}</Text>}\n mine={message.mine}\n timestamp={<Text data-ui-id={ids.messageTimestamp}>{formattedTimestamp}</Text>}\n details={getMessageDetails()}\n positionActionMenu={false}\n actionMenu={actionMenuProps}\n onTouchStart={() => setWasInteractionByTouch(true)}\n onPointerDown={() => setWasInteractionByTouch(false)}\n onKeyDown={() => setWasInteractionByTouch(false)}\n onBlur={() => setWasInteractionByTouch(false)}\n onClick={() => {\n if (!wasInteractionByTouch) {\n return;\n }\n // If the message was touched via touch we immediately open the menu\n // flyout (when using mouse the 3-dot menu that appears on hover\n // must be clicked to open the flyout).\n // In doing so here we set the target of the flyout to be the message and\n // not the 3-dot menu button to position the flyout correctly.\n setChatMessageActionFlyoutTarget(messageRef);\n if (message.messageType === 'chat') {\n props.onActionButtonClick(message, setMessageReadBy);\n }\n }}\n />\n </div>\n {chatActionsEnabled && (\n <ChatMessageActionFlyout\n hidden={!chatMessageActionFlyoutTarget}\n target={chatMessageActionFlyoutTarget}\n increaseFlyoutItemSize={wasInteractionByTouch}\n onDismiss={onActionFlyoutDismiss}\n onEditClick={onEditClick}\n onRemoveClick={onRemoveClick}\n onResendClick={onResendClick}\n strings={strings}\n messageReadBy={messageReadBy}\n messageStatus={messageStatus ?? 'failed'}\n remoteParticipantsCount={remoteParticipantsCount}\n onRenderAvatar={onRenderAvatar}\n showMessageStatus={showMessageStatus}\n />\n )}\n </>\n );\n\n return chatMessage;\n};\n\n/** @private */\nexport const ChatMessageComponentAsMessageBubble = React.memo(MessageBubble);\n\"../../../../acs-ui-common/src\""]}
|
1
|
+
{"version":3,"file":"ChatMessageComponentAsMessageBubble.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageComponentAsMessageBubble.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport { IStyle, mergeStyles } from '@fluentui/react';\nimport { Chat, Text, ComponentSlotStyle } from '@fluentui/react-northstar';\nimport { _formatString } from '@internal/acs-ui-common';\nimport React, { useCallback, useRef, useState } from 'react';\nimport {\n chatMessageEditedTagStyle,\n chatMessageDateStyle,\n chatMessageFailedTagStyle\n} from '../styles/ChatMessageComponent.styles';\nimport { formatTimeForChatMessage, formatTimestampForChatMessage } from '../utils/Datetime';\nimport { useIdentifiers } from '../../identifiers/IdentifierProvider';\nimport { useTheme } from '../../theming';\nimport { ChatMessageActionFlyout } from './ChatMessageActionsFlyout';\nimport { ChatMessageContent } from './ChatMessageContent';\nimport { ChatMessage } from '../../types/ChatMessage';\nimport { MessageThreadStrings } from '../MessageThread';\nimport { chatMessageActionMenuProps } from './ChatMessageActionMenu';\nimport { OnRenderAvatarCallback } from '../../types';\nimport { _FileDownloadCards, FileDownloadHandler } from '../FileDownloadCards';\nimport { ComponentLocale, useLocale } from '../../localization';\n\ntype ChatMessageComponentAsMessageBubbleProps = {\n message: ChatMessage;\n messageContainerStyle?: ComponentSlotStyle;\n showDate?: boolean;\n disableEditing?: boolean;\n onEditClick: () => void;\n onRemoveClick?: () => void;\n onResendClick?: () => void;\n strings: MessageThreadStrings;\n userId: string;\n messageStatus?: string;\n /**\n * Whether the status indicator for each message is displayed or not.\n */\n showMessageStatus?: boolean;\n /**\n * Optional callback to render uploaded files in the message component.\n */\n onRenderFileDownloads?: (userId: string, message: ChatMessage) => JSX.Element;\n /**\n * Optional function called when someone clicks on the file download icon.\n */\n fileDownloadHandler?: FileDownloadHandler;\n remoteParticipantsCount?: number;\n onActionButtonClick: (\n message: ChatMessage,\n setMessageReadBy: (readBy: { id: string; displayName: string }[]) => void\n ) => void;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n\n /**\n * Optional function to provide customized date format.\n * @beta\n */\n onDisplayDateTimeString?: (messageDate: Date) => string;\n};\n\nconst generateDefaultTimestamp = (\n createdOn: Date,\n showDate: boolean | undefined,\n strings: MessageThreadStrings\n): string => {\n const formattedTimestamp = showDate\n ? formatTimestampForChatMessage(createdOn, new Date(), strings)\n : formatTimeForChatMessage(createdOn);\n\n return formattedTimestamp;\n};\n\n// onDisplayDateTimeString from props overwrite onDisplayDateTimeString from locale\nconst generateCustomizedTimestamp = (\n props: ChatMessageComponentAsMessageBubbleProps,\n createdOn: Date,\n locale: ComponentLocale\n): string => {\n /* @conditional-compile-remove(date-time-customization) */\n return props.onDisplayDateTimeString\n ? props.onDisplayDateTimeString(createdOn)\n : locale.onDisplayDateTimeString\n ? locale.onDisplayDateTimeString(createdOn)\n : '';\n\n return '';\n};\n/** @private */\nconst MessageBubble = (props: ChatMessageComponentAsMessageBubbleProps): JSX.Element => {\n const ids = useIdentifiers();\n const theme = useTheme();\n const locale = useLocale();\n\n const {\n userId,\n message,\n onRemoveClick,\n onResendClick,\n disableEditing,\n showDate,\n messageContainerStyle,\n strings,\n onEditClick,\n remoteParticipantsCount = 0,\n onRenderAvatar,\n showMessageStatus,\n messageStatus,\n fileDownloadHandler\n } = props;\n\n const defaultTimeStamp = message.createdOn\n ? generateDefaultTimestamp(message.createdOn, showDate, strings)\n : undefined;\n\n const customTimestamp = message.createdOn ? generateCustomizedTimestamp(props, message.createdOn, locale) : '';\n\n const formattedTimestamp = customTimestamp || defaultTimeStamp;\n\n // Track if the action menu was opened by touch - if so we increase the touch targets for the items\n const [wasInteractionByTouch, setWasInteractionByTouch] = useState(false);\n\n // The chat message action flyout should target the Chat.Message action menu if clicked,\n // or target the chat message if opened via touch press.\n // Undefined indicates the flyout menu should not be being shown.\n const messageRef = useRef<HTMLDivElement | null>(null);\n const messageActionButtonRef = useRef<HTMLElement | null>(null);\n const [chatMessageActionFlyoutTarget, setChatMessageActionFlyoutTarget] = useState<\n React.MutableRefObject<HTMLElement | null> | undefined\n >(undefined);\n\n const chatActionsEnabled = !disableEditing && message.status !== 'sending' && !!message.mine;\n const [messageReadBy, setMessageReadBy] = useState<{ id: string; displayName: string }[]>([]);\n\n const actionMenuProps = wasInteractionByTouch\n ? undefined\n : chatMessageActionMenuProps({\n ariaLabel: strings.actionMenuMoreOptions ?? '',\n enabled: chatActionsEnabled,\n menuButtonRef: messageActionButtonRef,\n // Force show the action button while the flyout is open (otherwise this will dismiss when the pointer is hovered over the flyout)\n forceShow: chatMessageActionFlyoutTarget === messageActionButtonRef,\n onActionButtonClick: () => {\n props.onActionButtonClick(message, setMessageReadBy);\n setChatMessageActionFlyoutTarget(messageActionButtonRef);\n },\n theme\n });\n\n const onActionFlyoutDismiss = useCallback((): void => {\n // When the flyout dismiss is called, since we control if the action flyout is visible\n // or not we need to set the target to undefined here to actually hide the action flyout\n setChatMessageActionFlyoutTarget(undefined);\n }, [setChatMessageActionFlyoutTarget]);\n\n const defaultOnRenderFileDownloads = useCallback(\n () => (\n <_FileDownloadCards\n userId={userId}\n fileMetadata={message['attachedFilesMetadata'] || []}\n downloadHandler={fileDownloadHandler}\n /* @conditional-compile-remove(file-sharing) */\n strings={{ downloadFile: props.strings.downloadFile ?? locale.strings.messageThread.downloadFile }}\n />\n ),\n [\n userId,\n message,\n /* @conditional-compile-remove(file-sharing) */\n props,\n /* @conditional-compile-remove(file-sharing) */\n locale,\n fileDownloadHandler\n ]\n );\n\n const messageContentAriaText = props.message.content\n ? props.message.mine\n ? _formatString(strings.messageContentMineAriaText, {\n message: props.message.content\n })\n : _formatString(strings.messageContentAriaText, {\n author: `${props.message.senderDisplayName}`,\n message: props.message.content\n })\n : undefined;\n\n const chatMessage = (\n <>\n <div ref={messageRef}>\n <Chat.Message\n data-ui-id=\"chat-composite-message\"\n className={mergeStyles(messageContainerStyle as IStyle)}\n styles={messageContainerStyle}\n content={\n <div tabIndex={0}>\n <ChatMessageContent\n message={message}\n liveAuthorIntro={strings.liveAuthorIntro}\n messageContentAriaText={messageContentAriaText}\n />\n {props.onRenderFileDownloads\n ? props.onRenderFileDownloads(userId, message)\n : defaultOnRenderFileDownloads()}\n </div>\n }\n author={<Text className={chatMessageDateStyle}>{message.senderDisplayName}</Text>}\n mine={message.mine}\n timestamp={<Text data-ui-id={ids.messageTimestamp}>{formattedTimestamp}</Text>}\n details={\n messageStatus === 'failed' ? (\n <div className={chatMessageFailedTagStyle(theme)}>{strings.failToSendTag}</div>\n ) : message.editedOn ? (\n <div className={chatMessageEditedTagStyle(theme)}>{strings.editedTag}</div>\n ) : undefined\n }\n positionActionMenu={false}\n actionMenu={actionMenuProps}\n onTouchStart={() => setWasInteractionByTouch(true)}\n onPointerDown={() => setWasInteractionByTouch(false)}\n onKeyDown={() => setWasInteractionByTouch(false)}\n onBlur={() => setWasInteractionByTouch(false)}\n onClick={() => {\n if (!wasInteractionByTouch) {\n return;\n }\n // If the message was touched via touch we immediately open the menu\n // flyout (when using mouse the 3-dot menu that appears on hover\n // must be clicked to open the flyout).\n // In doing so here we set the target of the flyout to be the message and\n // not the 3-dot menu button to position the flyout correctly.\n setChatMessageActionFlyoutTarget(messageRef);\n props.onActionButtonClick(message, setMessageReadBy);\n }}\n />\n </div>\n {chatActionsEnabled && (\n <ChatMessageActionFlyout\n hidden={!chatMessageActionFlyoutTarget}\n target={chatMessageActionFlyoutTarget}\n increaseFlyoutItemSize={wasInteractionByTouch}\n onDismiss={onActionFlyoutDismiss}\n onEditClick={onEditClick}\n onRemoveClick={onRemoveClick}\n onResendClick={onResendClick}\n strings={strings}\n messageReadBy={messageReadBy}\n messageStatus={messageStatus ?? 'failed'}\n remoteParticipantsCount={remoteParticipantsCount}\n onRenderAvatar={onRenderAvatar}\n showMessageStatus={showMessageStatus}\n />\n )}\n </>\n );\n\n return chatMessage;\n};\n\n/** @private */\nexport const ChatMessageComponentAsMessageBubble = React.memo(MessageBubble);\n\"../../../../acs-ui-common/src\""]}
|
@@ -1,20 +1,11 @@
|
|
1
1
|
/// <reference types="react" />
|
2
2
|
import { ChatMessage } from '../../types/ChatMessage';
|
3
|
-
import { BlockedMessage } from '../../types/ChatMessage';
|
4
|
-
import { MessageThreadStrings } from '../MessageThread';
|
5
3
|
declare type ChatMessageContentProps = {
|
6
4
|
message: ChatMessage;
|
7
|
-
|
8
|
-
|
9
|
-
declare type BlockedMessageContentProps = {
|
10
|
-
message: BlockedMessage;
|
11
|
-
strings: MessageThreadStrings;
|
5
|
+
liveAuthorIntro: string;
|
6
|
+
messageContentAriaText?: string;
|
12
7
|
};
|
13
8
|
/** @private */
|
14
9
|
export declare const ChatMessageContent: (props: ChatMessageContentProps) => JSX.Element;
|
15
|
-
/**
|
16
|
-
* @private
|
17
|
-
*/
|
18
|
-
export declare const BlockedMessageContent: (props: BlockedMessageContentProps) => JSX.Element;
|
19
10
|
export {};
|
20
11
|
//# sourceMappingURL=ChatMessageContent.d.ts.map
|
@@ -6,8 +6,6 @@ import { Parser } from 'html-to-react';
|
|
6
6
|
import Linkify from 'react-linkify';
|
7
7
|
import { LiveMessage } from 'react-aria-live';
|
8
8
|
import { Link } from '@fluentui/react';
|
9
|
-
/* @conditional-compile-remove(data-loss-prevention) */
|
10
|
-
import { FontIcon, Stack } from '@fluentui/react';
|
11
9
|
/** @private */
|
12
10
|
export const ChatMessageContent = (props) => {
|
13
11
|
switch (props.message.contentType) {
|
@@ -22,44 +20,20 @@ export const ChatMessageContent = (props) => {
|
|
22
20
|
return React.createElement(React.Fragment, null);
|
23
21
|
}
|
24
22
|
};
|
25
|
-
const MessageContentWithLiveAria = (props) => {
|
26
|
-
return (React.createElement("div", { "data-ui-status": props.message.status, role: "text", "aria-label": props.ariaLabel },
|
27
|
-
React.createElement(LiveMessage, { message: props.liveMessage, "aria-live": "polite" }),
|
28
|
-
props.content));
|
29
|
-
};
|
30
23
|
const MessageContentAsRichTextHTML = (props) => {
|
31
24
|
const htmlToReactParser = new Parser();
|
32
|
-
const liveAuthor = _formatString(props.
|
33
|
-
return (React.createElement(
|
25
|
+
const liveAuthor = _formatString(props.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });
|
26
|
+
return (React.createElement("div", { "data-ui-status": props.message.status, role: "text", "aria-label": props.messageContentAriaText },
|
27
|
+
React.createElement(LiveMessage, { message: `${props.message.mine ? '' : liveAuthor} ${extractContent(props.message.content || '')}`, "aria-live": "polite" }),
|
28
|
+
htmlToReactParser.parse(props.message.content)));
|
34
29
|
};
|
35
30
|
const MessageContentAsText = (props) => {
|
36
|
-
const liveAuthor = _formatString(props.
|
37
|
-
return (React.createElement(
|
31
|
+
const liveAuthor = _formatString(props.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });
|
32
|
+
return (React.createElement("div", { "data-ui-status": props.message.status, role: "text", "aria-label": props.messageContentAriaText },
|
33
|
+
React.createElement(LiveMessage, { message: `${props.message.mine ? '' : liveAuthor} ${props.message.content}`, "aria-live": "polite" }),
|
34
|
+
React.createElement(Linkify, { componentDecorator: (decoratedHref, decoratedText, key) => {
|
38
35
|
return (React.createElement(Link, { target: "_blank", href: decoratedHref, key: key }, decoratedText));
|
39
|
-
} }, props.message.content)
|
40
|
-
};
|
41
|
-
/* @conditional-compile-remove(data-loss-prevention) */
|
42
|
-
/**
|
43
|
-
* @private
|
44
|
-
*/
|
45
|
-
export const BlockedMessageContent = (props) => {
|
46
|
-
var _a;
|
47
|
-
const Icon = React.createElement(FontIcon, { iconName: 'DataLossPreventionProhibited' });
|
48
|
-
const blockedMessage = props.message.warningText === false
|
49
|
-
? ''
|
50
|
-
: props.message.warningText === '' || props.message.warningText === undefined
|
51
|
-
? props.strings.blockedWarningText
|
52
|
-
: props.message.warningText;
|
53
|
-
const blockedMessageLink = props.message.link;
|
54
|
-
const blockedMessageLinkText = blockedMessageLink
|
55
|
-
? (_a = props.message.linkText) !== null && _a !== void 0 ? _a : props.strings.blockedWarningLinkText
|
56
|
-
: '';
|
57
|
-
const liveAuthor = props.message.mine || props.message.senderDisplayName === undefined ? '' : props.message.senderDisplayName;
|
58
|
-
const liveBlockedWarningText = `${liveAuthor} ${blockedMessage} ${blockedMessageLinkText}`;
|
59
|
-
return (React.createElement(MessageContentWithLiveAria, { message: props.message, liveMessage: liveBlockedWarningText, ariaLabel: liveBlockedWarningText, content: React.createElement(Stack, { horizontal: true, wrap: true },
|
60
|
-
Icon,
|
61
|
-
blockedMessage && React.createElement("p", null, blockedMessage),
|
62
|
-
blockedMessageLink && (React.createElement(Link, { target: '_blank', href: blockedMessageLink }, blockedMessageLinkText))) }));
|
36
|
+
} }, props.message.content)));
|
63
37
|
};
|
64
38
|
// https://stackoverflow.com/questions/28899298/extract-the-text-out-of-html-string-using-javascript
|
65
39
|
const extractContent = (s) => {
|
@@ -67,16 +41,4 @@ const extractContent = (s) => {
|
|
67
41
|
span.innerHTML = s;
|
68
42
|
return span.textContent || span.innerText;
|
69
43
|
};
|
70
|
-
const messageContentAriaText = (props) => {
|
71
|
-
return props.message.content
|
72
|
-
? props.message.mine
|
73
|
-
? _formatString(props.strings.messageContentMineAriaText, {
|
74
|
-
message: props.message.content
|
75
|
-
})
|
76
|
-
: _formatString(props.strings.messageContentAriaText, {
|
77
|
-
author: `${props.message.senderDisplayName}`,
|
78
|
-
message: props.message.content
|
79
|
-
})
|
80
|
-
: undefined;
|
81
|
-
};
|
82
44
|
//# sourceMappingURL=ChatMessageContent.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"ChatMessageContent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageContent.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAElC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,aAAa,EAAE,sCAAgC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AACvC,OAAO,OAAO,MAAM,eAAe,CAAC;
|
1
|
+
{"version":3,"file":"ChatMessageContent.js","sourceRoot":"","sources":["../../../../../../../react-components/src/components/ChatMessage/ChatMessageContent.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\n\nimport React from 'react';\nimport { _formatString } from '@internal/acs-ui-common';\nimport { Parser } from 'html-to-react';\nimport Linkify from 'react-linkify';\nimport { ChatMessage } from '../../types/ChatMessage';\nimport { LiveMessage } from 'react-aria-live';\nimport { Link } from '@fluentui/react';\n\ntype ChatMessageContentProps = {\n message: ChatMessage;\n liveAuthorIntro: string;\n messageContentAriaText?: string;\n};\n\n/** @private */\nexport const ChatMessageContent = (props: ChatMessageContentProps): JSX.Element => {\n switch (props.message.contentType) {\n case 'text':\n return MessageContentAsText(props);\n case 'html':\n return MessageContentAsRichTextHTML(props);\n case 'richtext/html':\n return MessageContentAsRichTextHTML(props);\n default:\n console.warn('unknown message content type');\n return <></>;\n }\n};\n\nconst MessageContentAsRichTextHTML = (props: ChatMessageContentProps): JSX.Element => {\n const htmlToReactParser = new Parser();\n const liveAuthor = _formatString(props.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n return (\n <div data-ui-status={props.message.status} role=\"text\" aria-label={props.messageContentAriaText}>\n <LiveMessage\n message={`${props.message.mine ? '' : liveAuthor} ${extractContent(props.message.content || '')}`}\n aria-live=\"polite\"\n />\n {htmlToReactParser.parse(props.message.content)}\n </div>\n );\n};\n\nconst MessageContentAsText = (props: ChatMessageContentProps): JSX.Element => {\n const liveAuthor = _formatString(props.liveAuthorIntro, { author: `${props.message.senderDisplayName}` });\n return (\n <div data-ui-status={props.message.status} role=\"text\" aria-label={props.messageContentAriaText}>\n <LiveMessage message={`${props.message.mine ? '' : liveAuthor} ${props.message.content}`} aria-live=\"polite\" />\n <Linkify\n componentDecorator={(decoratedHref: string, decoratedText: string, key: number) => {\n return (\n <Link target=\"_blank\" href={decoratedHref} key={key}>\n {decoratedText}\n </Link>\n );\n }}\n >\n {props.message.content}\n </Linkify>\n </div>\n );\n};\n\n// https://stackoverflow.com/questions/28899298/extract-the-text-out-of-html-string-using-javascript\nconst extractContent = (s: string): string => {\n const span = document.createElement('span');\n span.innerHTML = s;\n return span.textContent || span.innerText;\n};\n\"../../../../acs-ui-common/src\""]}
|
@@ -1,15 +1,9 @@
|
|
1
1
|
/// <reference types="react" />
|
2
|
-
/**
|
3
|
-
* @beta
|
4
|
-
*/
|
5
|
-
export declare type FileMetadataAttachmentType = 'fileSharing' | /* @conditional-compile-remove(teams-inline-images) */ 'teamsInlineImage' | 'unknown';
|
6
2
|
/**
|
7
3
|
* Meta Data containing information about the uploaded file.
|
8
4
|
* @beta
|
9
5
|
*/
|
10
6
|
export interface FileMetadata {
|
11
|
-
attachmentType: FileMetadataAttachmentType;
|
12
|
-
id: string;
|
13
7
|
/**
|
14
8
|
* File name to be displayed.
|
15
9
|
*/
|
@@ -24,7 +18,6 @@ export interface FileMetadata {
|
|
24
18
|
* Download URL for the file.
|
25
19
|
*/
|
26
20
|
url: string;
|
27
|
-
previewUrl?: string;
|
28
21
|
}
|
29
22
|
/**
|
30
23
|
* Strings of _FileDownloadCards that can be overridden.
|
@@ -56,11 +56,7 @@ export const _FileDownloadCards = (props) => {
|
|
56
56
|
}
|
57
57
|
}
|
58
58
|
}), [props]);
|
59
|
-
|
60
|
-
// Since you can't have both fileSharing and teamsInlineImage in the same message.
|
61
|
-
if (!fileMetadata ||
|
62
|
-
fileMetadata.length === 0 ||
|
63
|
-
/* @conditional-compile-remove(teams-inline-images) */ fileMetadata[0].attachmentType !== 'fileSharing') {
|
59
|
+
if (!fileMetadata || fileMetadata.length === 0) {
|
64
60
|
return React.createElement(React.Fragment, null);
|
65
61
|
}
|
66
62
|
return (React.createElement("div", { style: fileDownloadCardsStyle, "data-ui-id": "file-download-card-group" },
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"FileDownloadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/FileDownloadCards.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { Icon, IconButton, Spinner, SpinnerSize } from '@fluentui/react';\nimport React, { useCallback, useState } from 'react';\nimport { useMemo } from 'react';\n/* @conditional-compile-remove(file-sharing) */\nimport { useLocale } from '../localization';\nimport { _FileCard } from './FileCard';\nimport { _FileCardGroup } from './FileCardGroup';\nimport { iconButtonClassName } from './styles/IconButton.styles';\n\n/* @conditional-compile-remove(teams-inline-images) */\n/**\n * @beta\n */\nexport type FileMetadataAttachmentType =\n | 'fileSharing'\n | /* @conditional-compile-remove(teams-inline-images) */ 'teamsInlineImage'\n | 'unknown';\n\n/**\n * Meta Data containing information about the uploaded file.\n * @beta\n */\nexport interface FileMetadata {\n /* @conditional-compile-remove(teams-inline-images) */\n /*\n * Attachment type of the file.\n * Possible values {@link FileDownloadHandler}.\n */\n attachmentType: FileMetadataAttachmentType;\n /* @conditional-compile-remove(teams-inline-images) */\n /*\n * Unique ID of the file.\n */\n id: string;\n /**\n * File name to be displayed.\n */\n name: string;\n /**\n * Extension is used for rendering the file icon.\n * An unknown extension will be rendered as a generic icon.\n * Example: `jpeg`\n */\n extension: string;\n /**\n * Download URL for the file.\n */\n url: string;\n /* @conditional-compile-remove(teams-inline-images) */\n /*\n * Preview URL for the file.\n * Used in the message bubble for inline images.\n */\n previewUrl?: string;\n}\n\n/**\n * Strings of _FileDownloadCards that can be overridden.\n *\n * @internal\n */\nexport interface _FileDownloadCardsStrings {\n /** Aria label to notify user when focus is on file download button. */\n downloadFile: string;\n}\n\n/**\n * @beta\n * A file download error returned via a {@link FileDownloadHandler}.\n * This error message is used to render an error message in the UI.\n */\nexport interface FileDownloadError {\n /** The error message to display in the UI */\n errorMessage: string;\n}\n\n/**\n * @beta\n *\n * A callback function for handling file downloads.\n * The function needs to return a promise that resolves to a file download URL.\n * If the promise is rejected, the {@link Error.message} will be used to display an error message to the user.\n *\n * @example\n * ```ts\n * const fileDownloadHandler: FileDownloadHandler = async (userId, fileData) => {\n * if (isUnauthorizedUser(userId)) {\n * return { errorMessage: 'You don’t have permission to download this file.' };\n * } else {\n * return new URL(fileData.url);\n * }\n * }\n *\n * const App = () => (\n * <ChatComposite\n * ...\n * fileSharing={{\n * fileDownloadHandler: fileDownloadHandler\n * }}\n * />\n * )\n *\n * ```\n * @param userId - The user ID of the user downloading the file.\n * @param fileMetadata - The {@link FileMetadata} containing file `url`, `extension` and `name`.\n */\nexport type FileDownloadHandler = (userId: string, fileMetadata: FileMetadata) => Promise<URL | FileDownloadError>;\n\n/**\n * @internal\n */\nexport interface _FileDownloadCards {\n /**\n * User id of the local participant\n */\n userId: string;\n /**\n * A chat message metadata that inculdes file metadata\n */\n fileMetadata: FileMetadata[];\n /**\n * A function of type {@link FileDownloadHandler} for handling file downloads.\n * If the function is not specified, the file's `url` will be opened in a new tab to\n * initiate the download.\n */\n downloadHandler?: FileDownloadHandler;\n /**\n * Optional callback that runs if downloadHandler returns {@link FileDownloadError}.\n */\n onDownloadErrorMessage?: (errMsg: string) => void;\n /**\n * Optional arialabel strings for file download cards\n */\n strings?: _FileDownloadCardsStrings;\n}\n\nconst fileDownloadCardsStyle = {\n marginTop: '0.25rem'\n};\n\nconst actionIconStyle = { height: '1rem' };\n\n/**\n * @internal\n */\nexport const _FileDownloadCards = (props: _FileDownloadCards): JSX.Element => {\n const { userId, fileMetadata } = props;\n const [showSpinner, setShowSpinner] = useState(false);\n const localeStrings = useLocaleStringsTrampoline();\n\n const downloadFileButtonString = useMemo(\n () => () => {\n return props.strings?.downloadFile ?? localeStrings.downloadFile;\n // Return download button without aria label\n return props.strings?.downloadFile ?? '';\n },\n [props.strings?.downloadFile, localeStrings.downloadFile]\n );\n\n const fileDownloadHandler = useCallback(\n async (userId, file) => {\n if (!props.downloadHandler) {\n window.open(file.url, '_blank', 'noopener,noreferrer');\n } else {\n setShowSpinner(true);\n try {\n const response = await props.downloadHandler(userId, file);\n setShowSpinner(false);\n if (response instanceof URL) {\n window.open(response.toString(), '_blank', 'noopener,noreferrer');\n } else {\n props.onDownloadErrorMessage && props.onDownloadErrorMessage(response.errorMessage);\n }\n } finally {\n setShowSpinner(false);\n }\n }\n },\n [props]\n );\n // Its safe to assume that if the first item in the fileMetadata is not a fileSharing type we don't want to display the FileDownloadCard.\n // Since you can't have both fileSharing and teamsInlineImage in the same message.\n if (\n !fileMetadata ||\n fileMetadata.length === 0 ||\n /* @conditional-compile-remove(teams-inline-images) */ fileMetadata[0].attachmentType !== 'fileSharing'\n ) {\n return <></>;\n }\n\n return (\n <div style={fileDownloadCardsStyle} data-ui-id=\"file-download-card-group\">\n <_FileCardGroup>\n {fileMetadata &&\n fileMetadata.map((file) => (\n <_FileCard\n fileName={file.name}\n key={file.name}\n fileExtension={file.extension}\n actionIcon={\n showSpinner ? (\n <Spinner size={SpinnerSize.medium} aria-live={'polite'} role={'status'} />\n ) : (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n )\n }\n actionHandler={() => fileDownloadHandler(userId, file)}\n />\n ))}\n </_FileCardGroup>\n </div>\n );\n};\n\n/**\n * @private\n */\nconst DownloadIconTrampoline = (): JSX.Element => {\n // @conditional-compile-remove(file-sharing)\n return <Icon data-ui-id=\"file-download-card-download-icon\" iconName=\"DownloadFile\" style={actionIconStyle} />;\n // Return _some_ available icon, as the real icon is beta-only.\n return <Icon iconName=\"EditBoxCancel\" style={actionIconStyle} />;\n};\n\nconst useLocaleStringsTrampoline = (): _FileDownloadCardsStrings => {\n /* @conditional-compile-remove(file-sharing) */\n return useLocale().strings.messageThread;\n return { downloadFile: '' };\n};\n"]}
|
1
|
+
{"version":3,"file":"FileDownloadCards.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/FileDownloadCards.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT license.\nimport { Icon, IconButton, Spinner, SpinnerSize } from '@fluentui/react';\nimport React, { useCallback, useState } from 'react';\nimport { useMemo } from 'react';\n/* @conditional-compile-remove(file-sharing) */\nimport { useLocale } from '../localization';\nimport { _FileCard } from './FileCard';\nimport { _FileCardGroup } from './FileCardGroup';\nimport { iconButtonClassName } from './styles/IconButton.styles';\n\n/**\n * Meta Data containing information about the uploaded file.\n * @beta\n */\nexport interface FileMetadata {\n /**\n * File name to be displayed.\n */\n name: string;\n /**\n * Extension is used for rendering the file icon.\n * An unknown extension will be rendered as a generic icon.\n * Example: `jpeg`\n */\n extension: string;\n /**\n * Download URL for the file.\n */\n url: string;\n}\n\n/**\n * Strings of _FileDownloadCards that can be overridden.\n *\n * @internal\n */\nexport interface _FileDownloadCardsStrings {\n /** Aria label to notify user when focus is on file download button. */\n downloadFile: string;\n}\n\n/**\n * @beta\n * A file download error returned via a {@link FileDownloadHandler}.\n * This error message is used to render an error message in the UI.\n */\nexport interface FileDownloadError {\n /** The error message to display in the UI */\n errorMessage: string;\n}\n\n/**\n * @beta\n *\n * A callback function for handling file downloads.\n * The function needs to return a promise that resolves to a file download URL.\n * If the promise is rejected, the {@link Error.message} will be used to display an error message to the user.\n *\n * @example\n * ```ts\n * const fileDownloadHandler: FileDownloadHandler = async (userId, fileData) => {\n * if (isUnauthorizedUser(userId)) {\n * return { errorMessage: 'You don’t have permission to download this file.' };\n * } else {\n * return new URL(fileData.url);\n * }\n * }\n *\n * const App = () => (\n * <ChatComposite\n * ...\n * fileSharing={{\n * fileDownloadHandler: fileDownloadHandler\n * }}\n * />\n * )\n *\n * ```\n * @param userId - The user ID of the user downloading the file.\n * @param fileMetadata - The {@link FileMetadata} containing file `url`, `extension` and `name`.\n */\nexport type FileDownloadHandler = (userId: string, fileMetadata: FileMetadata) => Promise<URL | FileDownloadError>;\n\n/**\n * @internal\n */\nexport interface _FileDownloadCards {\n /**\n * User id of the local participant\n */\n userId: string;\n /**\n * A chat message metadata that inculdes file metadata\n */\n fileMetadata: FileMetadata[];\n /**\n * A function of type {@link FileDownloadHandler} for handling file downloads.\n * If the function is not specified, the file's `url` will be opened in a new tab to\n * initiate the download.\n */\n downloadHandler?: FileDownloadHandler;\n /**\n * Optional callback that runs if downloadHandler returns {@link FileDownloadError}.\n */\n onDownloadErrorMessage?: (errMsg: string) => void;\n /**\n * Optional arialabel strings for file download cards\n */\n strings?: _FileDownloadCardsStrings;\n}\n\nconst fileDownloadCardsStyle = {\n marginTop: '0.25rem'\n};\n\nconst actionIconStyle = { height: '1rem' };\n\n/**\n * @internal\n */\nexport const _FileDownloadCards = (props: _FileDownloadCards): JSX.Element => {\n const { userId, fileMetadata } = props;\n const [showSpinner, setShowSpinner] = useState(false);\n const localeStrings = useLocaleStringsTrampoline();\n\n const downloadFileButtonString = useMemo(\n () => () => {\n return props.strings?.downloadFile ?? localeStrings.downloadFile;\n // Return download button without aria label\n return props.strings?.downloadFile ?? '';\n },\n [props.strings?.downloadFile, localeStrings.downloadFile]\n );\n\n const fileDownloadHandler = useCallback(\n async (userId, file) => {\n if (!props.downloadHandler) {\n window.open(file.url, '_blank', 'noopener,noreferrer');\n } else {\n setShowSpinner(true);\n try {\n const response = await props.downloadHandler(userId, file);\n setShowSpinner(false);\n if (response instanceof URL) {\n window.open(response.toString(), '_blank', 'noopener,noreferrer');\n } else {\n props.onDownloadErrorMessage && props.onDownloadErrorMessage(response.errorMessage);\n }\n } finally {\n setShowSpinner(false);\n }\n }\n },\n [props]\n );\n\n if (!fileMetadata || fileMetadata.length === 0) {\n return <></>;\n }\n\n return (\n <div style={fileDownloadCardsStyle} data-ui-id=\"file-download-card-group\">\n <_FileCardGroup>\n {fileMetadata &&\n fileMetadata.map((file) => (\n <_FileCard\n fileName={file.name}\n key={file.name}\n fileExtension={file.extension}\n actionIcon={\n showSpinner ? (\n <Spinner size={SpinnerSize.medium} aria-live={'polite'} role={'status'} />\n ) : (\n <IconButton className={iconButtonClassName} ariaLabel={downloadFileButtonString()}>\n <DownloadIconTrampoline />\n </IconButton>\n )\n }\n actionHandler={() => fileDownloadHandler(userId, file)}\n />\n ))}\n </_FileCardGroup>\n </div>\n );\n};\n\n/**\n * @private\n */\nconst DownloadIconTrampoline = (): JSX.Element => {\n // @conditional-compile-remove(file-sharing)\n return <Icon data-ui-id=\"file-download-card-download-icon\" iconName=\"DownloadFile\" style={actionIconStyle} />;\n // Return _some_ available icon, as the real icon is beta-only.\n return <Icon iconName=\"EditBoxCancel\" style={actionIconStyle} />;\n};\n\nconst useLocaleStringsTrampoline = (): _FileDownloadCardsStrings => {\n /* @conditional-compile-remove(file-sharing) */\n return useLocale().strings.messageThread;\n return { downloadFile: '' };\n};\n"]}
|
@@ -2,7 +2,6 @@
|
|
2
2
|
import { IStyle } from '@fluentui/react';
|
3
3
|
import { ComponentSlotStyle } from '@fluentui/react-northstar';
|
4
4
|
import { BaseCustomStyles, ChatMessage, CustomMessage, SystemMessage, OnRenderAvatarCallback, Message, ReadReceiptsBySenderId } from '../types';
|
5
|
-
import { BlockedMessage } from '../types';
|
6
5
|
import { MessageStatusIndicatorProps } from './MessageStatusIndicator';
|
7
6
|
import { FileDownloadHandler, FileMetadata } from './FileDownloadCards';
|
8
7
|
/**
|
@@ -29,8 +28,6 @@ export interface MessageThreadStyles extends BaseCustomStyles {
|
|
29
28
|
chatMessageContainer?: ComponentSlotStyle;
|
30
29
|
/** Styles for system message container. */
|
31
30
|
systemMessageContainer?: ComponentSlotStyle;
|
32
|
-
/** Styles for blocked message container. */
|
33
|
-
blockedMessageContainer?: ComponentSlotStyle;
|
34
31
|
/** Styles for message status indicator container. */
|
35
32
|
messageStatusContainer?: (mine: boolean) => IStyle;
|
36
33
|
}
|
@@ -94,10 +91,6 @@ export interface MessageThreadStrings {
|
|
94
91
|
actionMenuMoreOptions?: string;
|
95
92
|
/** String for download file button in file card */
|
96
93
|
downloadFile: string;
|
97
|
-
/** String for policy violation message removal */
|
98
|
-
blockedWarningText: string;
|
99
|
-
/** String for policy violation message removal details link */
|
100
|
-
blockedWarningLinkText: string;
|
101
94
|
}
|
102
95
|
/**
|
103
96
|
* Arguments for {@link MessageThreadProps.onRenderJumpToNewMessageButton}.
|
@@ -134,9 +127,9 @@ export declare type MessageThreadProps = {
|
|
134
127
|
*/
|
135
128
|
userId: string;
|
136
129
|
/**
|
137
|
-
* Messages to render in message thread. A message can be of type `ChatMessage`, `SystemMessage
|
130
|
+
* Messages to render in message thread. A message can be of type `ChatMessage`, `SystemMessage` or `CustomMessage`.
|
138
131
|
*/
|
139
|
-
messages: (ChatMessage | SystemMessage | CustomMessage
|
132
|
+
messages: (ChatMessage | SystemMessage | CustomMessage)[];
|
140
133
|
/**
|
141
134
|
* number of participants in the thread
|
142
135
|
*/
|
@@ -280,7 +273,7 @@ export declare type MessageThreadProps = {
|
|
280
273
|
*/
|
281
274
|
export declare type MessageProps = {
|
282
275
|
/**
|
283
|
-
* Message to render. It can type `ChatMessage` or `SystemMessage
|
276
|
+
* Message to render. It can type `ChatMessage` or `SystemMessage` or `CustomMessage`.
|
284
277
|
*/
|
285
278
|
message: Message;
|
286
279
|
/**
|