botframework-webchat-component 4.13.0 → 4.14.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/.eslintignore +1 -9
- package/.eslintrc.yml +6 -0
- package/lib/Activity/Avatar.d.ts +10 -0
- package/lib/Activity/Avatar.d.ts.map +1 -0
- package/lib/Activity/Avatar.js +2 -1
- package/lib/Activity/Bubble.d.ts +11 -0
- package/lib/Activity/Bubble.d.ts.map +1 -0
- package/lib/Activity/Bubble.js +2 -2
- package/lib/Activity/CarouselFilmStrip.js +20 -30
- package/lib/Activity/CarouselFilmStripAttachment.js +120 -0
- package/lib/Activity/CarouselLayout.js +5 -5
- package/lib/Activity/Speak.d.ts +10 -0
- package/lib/Activity/Speak.d.ts.map +1 -0
- package/lib/Activity/Speak.js +10 -12
- package/lib/Activity/StackedLayout.d.ts +18 -0
- package/lib/Activity/StackedLayout.d.ts.map +1 -0
- package/lib/Activity/StackedLayout.js +18 -14
- package/lib/Assets/TypingAnimation.js +2 -2
- package/lib/Attachment/Assets/DownloadIcon.js +3 -1
- package/lib/Attachment/AudioAttachment.js +2 -2
- package/lib/Attachment/AudioContent.d.ts +11 -0
- package/lib/Attachment/AudioContent.d.ts.map +1 -0
- package/lib/Attachment/AudioContent.js +4 -4
- package/lib/Attachment/FileContent.d.ts +10 -0
- package/lib/Attachment/FileContent.d.ts.map +1 -0
- package/lib/Attachment/FileContent.js +4 -9
- package/lib/Attachment/HTMLVideoContent.d.ts +11 -0
- package/lib/Attachment/HTMLVideoContent.d.ts.map +1 -0
- package/lib/Attachment/HTMLVideoContent.js +2 -2
- package/lib/Attachment/ImageContent.d.ts +8 -0
- package/lib/Attachment/ImageContent.d.ts.map +1 -0
- package/lib/Attachment/ImageContent.js +2 -2
- package/lib/Attachment/TextContent.d.ts +8 -0
- package/lib/Attachment/TextContent.d.ts.map +1 -0
- package/lib/Attachment/TextContent.js +4 -4
- package/lib/Attachment/VideoAttachment.js +2 -2
- package/lib/Attachment/VideoContent.d.ts +11 -0
- package/lib/Attachment/VideoContent.d.ts.map +1 -0
- package/lib/Attachment/VideoContent.js +1 -1
- package/lib/Attachment/VimeoContent.d.ts +10 -0
- package/lib/Attachment/VimeoContent.d.ts.map +1 -0
- package/lib/Attachment/VimeoContent.js +8 -8
- package/lib/Attachment/YouTubeContent.d.ts +10 -0
- package/lib/Attachment/YouTubeContent.d.ts.map +1 -0
- package/lib/Attachment/YouTubeContent.js +5 -5
- package/lib/Avatar/ImageAvatar.js +2 -2
- package/lib/Avatar/InitialsAvatar.js +2 -2
- package/lib/BasicConnectivityStatus.js +2 -2
- package/lib/BasicSendBox.d.ts +9 -0
- package/lib/BasicSendBox.d.ts.map +1 -0
- package/lib/BasicSendBox.js +6 -5
- package/lib/BasicToast.js +4 -4
- package/lib/BasicToaster.js +4 -4
- package/lib/BasicTranscript.js +143 -123
- package/lib/BasicTypingIndicator.d.ts +5 -0
- package/lib/BasicTypingIndicator.d.ts.map +1 -0
- package/lib/BasicTypingIndicator.js +2 -2
- package/lib/BasicWebChat.d.ts +9 -0
- package/lib/BasicWebChat.d.ts.map +1 -0
- package/lib/BasicWebChat.js +6 -4
- package/lib/Composer.d.ts +23 -0
- package/lib/Composer.d.ts.map +1 -0
- package/lib/Composer.js +33 -55
- package/lib/ConnectivityStatus/Assets/ErrorNotificationIcon.js +2 -2
- package/lib/ConnectivityStatus/Assets/SpinnerAnimation.js +2 -2
- package/lib/ConnectivityStatus/Assets/WarningNotificationIcon.js +2 -2
- package/lib/ConnectivityStatus/Connected.js +1 -1
- package/lib/ConnectivityStatus/Connecting.js +4 -4
- package/lib/ConnectivityStatus/FailedToConnect.js +2 -2
- package/lib/ConnectivityStatus/JavaScriptError.js +2 -2
- package/lib/Dictation.js +13 -4
- package/lib/ErrorBox.d.ts +8 -0
- package/lib/ErrorBox.d.ts.map +1 -0
- package/lib/ErrorBox.js +2 -2
- package/lib/Middleware/Activity/createCoreMiddleware.d.ts +3 -0
- package/lib/Middleware/Activity/createCoreMiddleware.d.ts.map +1 -0
- package/lib/Middleware/Activity/createCoreMiddleware.js +1 -1
- package/lib/Middleware/ActivityStatus/AbsoluteTime.js +1 -1
- package/lib/Middleware/ActivityStatus/RelativeTime.js +1 -1
- package/lib/Middleware/ActivityStatus/SendStatus/SendFailedRetry.js +3 -3
- package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.d.ts +11 -0
- package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.d.ts.map +1 -0
- package/lib/Middleware/ActivityStatus/SendStatus/SendStatus.js +4 -4
- package/lib/Middleware/ActivityStatus/Timestamp.d.ts +9 -0
- package/lib/Middleware/ActivityStatus/Timestamp.d.ts.map +1 -0
- package/lib/Middleware/ActivityStatus/Timestamp.js +2 -2
- package/lib/Middleware/ActivityStatus/createCoreMiddleware.d.ts +3 -0
- package/lib/Middleware/ActivityStatus/createCoreMiddleware.d.ts.map +1 -0
- package/lib/Middleware/ActivityStatus/createCoreMiddleware.js +1 -1
- package/lib/Middleware/ActivityStatus/createSendStatusMiddleware.js +5 -3
- package/lib/Middleware/ActivityStatus/createTimestampMiddleware.js +1 -1
- package/lib/Middleware/Attachment/createCoreMiddleware.d.ts +3 -0
- package/lib/Middleware/Attachment/createCoreMiddleware.d.ts.map +1 -0
- package/lib/Middleware/Attachment/createCoreMiddleware.js +9 -9
- package/lib/Middleware/AttachmentForScreenReader/AudioAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/FileAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/ImageAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/TextAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/VideoAttachment.js +1 -1
- package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts +3 -0
- package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.d.ts.map +1 -0
- package/lib/Middleware/AttachmentForScreenReader/createCoreMiddleware.js +9 -5
- package/lib/Middleware/Avatar/createCoreMiddleware.d.ts +11 -0
- package/lib/Middleware/Avatar/createCoreMiddleware.d.ts.map +1 -0
- package/lib/Middleware/Avatar/createCoreMiddleware.js +2 -2
- package/lib/Middleware/CardAction/createCoreMiddleware.js +2 -2
- package/lib/Middleware/GroupActivities/createCoreMiddleware.js +1 -1
- package/lib/Middleware/ScrollToEndButton/ScrollToEndButton.js +71 -0
- package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts +3 -0
- package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.d.ts.map +1 -0
- package/lib/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.js +27 -0
- package/lib/Middleware/Toast/createCoreMiddleware.d.ts +4 -0
- package/lib/Middleware/Toast/createCoreMiddleware.d.ts.map +1 -0
- package/lib/Middleware/Toast/createCoreMiddleware.js +1 -1
- package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts +3 -0
- package/lib/Middleware/TypingIndicator/createCoreMiddleware.d.ts.map +1 -0
- package/lib/Middleware/TypingIndicator/createCoreMiddleware.js +3 -2
- package/lib/ReactWebChat.d.ts +10 -0
- package/lib/ReactWebChat.d.ts.map +1 -0
- package/lib/ReactWebChat.js +19 -7
- package/lib/ScreenReaderActivity.js +64 -45
- package/lib/SendBox/Assets/AttachmentIcon.js +3 -1
- package/lib/SendBox/Assets/MicrophoneIcon.js +3 -1
- package/lib/SendBox/Assets/SendIcon.js +2 -2
- package/lib/SendBox/AutoResizeTextArea.d.ts +23 -0
- package/lib/SendBox/AutoResizeTextArea.d.ts.map +1 -0
- package/lib/SendBox/AutoResizeTextArea.js +6 -6
- package/lib/SendBox/DictationInterims.d.ts +9 -0
- package/lib/SendBox/DictationInterims.d.ts.map +1 -0
- package/lib/SendBox/DictationInterims.js +2 -2
- package/lib/SendBox/IconButton.js +2 -2
- package/lib/SendBox/MicrophoneButton.d.ts +11 -0
- package/lib/SendBox/MicrophoneButton.d.ts.map +1 -0
- package/lib/SendBox/MicrophoneButton.js +25 -24
- package/lib/SendBox/SendButton.d.ts +9 -0
- package/lib/SendBox/SendButton.d.ts.map +1 -0
- package/lib/SendBox/SendButton.js +7 -5
- package/lib/SendBox/SuggestedAction.js +5 -9
- package/lib/SendBox/SuggestedActions.d.ts +5 -0
- package/lib/SendBox/SuggestedActions.d.ts.map +1 -0
- package/lib/SendBox/SuggestedActions.js +10 -7
- package/lib/SendBox/TextBox.d.ts +28 -0
- package/lib/SendBox/TextBox.d.ts.map +1 -0
- package/lib/SendBox/TextBox.js +12 -7
- package/lib/SendBox/UploadButton.d.ts +9 -0
- package/lib/SendBox/UploadButton.d.ts.map +1 -0
- package/lib/SendBox/UploadButton.js +5 -5
- package/lib/Styles/StyleSet/Activities.d.ts +5 -0
- package/lib/Styles/StyleSet/Activities.d.ts.map +1 -0
- package/lib/Styles/StyleSet/AudioAttachment.d.ts +6 -0
- package/lib/Styles/StyleSet/AudioAttachment.d.ts.map +1 -0
- package/lib/Styles/StyleSet/AudioContent.d.ts +4 -0
- package/lib/Styles/StyleSet/AudioContent.d.ts.map +1 -0
- package/lib/Styles/StyleSet/AutoResizeTextArea.d.ts +37 -0
- package/lib/Styles/StyleSet/AutoResizeTextArea.d.ts.map +1 -0
- package/lib/Styles/StyleSet/Avatar.d.ts +9 -0
- package/lib/Styles/StyleSet/Avatar.d.ts.map +1 -0
- package/lib/Styles/StyleSet/BasicTranscript.d.ts +77 -0
- package/lib/Styles/StyleSet/BasicTranscript.d.ts.map +1 -0
- package/lib/Styles/StyleSet/Bubble.d.ts +5 -0
- package/lib/Styles/StyleSet/Bubble.d.ts.map +1 -0
- package/lib/Styles/StyleSet/Bubble.js +1 -1
- package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts +5 -0
- package/lib/Styles/StyleSet/CarouselFilmStrip.d.ts.map +1 -0
- package/lib/Styles/StyleSet/CarouselFilmStrip.js +2 -18
- package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts +3 -0
- package/lib/Styles/StyleSet/CarouselFilmStripAttachment.d.ts.map +1 -0
- package/lib/Styles/StyleSet/CarouselFilmStripAttachment.js +63 -0
- package/lib/Styles/StyleSet/CarouselFlipper.d.ts +27 -0
- package/lib/Styles/StyleSet/CarouselFlipper.d.ts.map +1 -0
- package/lib/Styles/StyleSet/ConnectivityNotification.d.ts +13 -0
- package/lib/Styles/StyleSet/ConnectivityNotification.d.ts.map +1 -0
- package/lib/Styles/StyleSet/DictationInterims.d.ts +13 -0
- package/lib/Styles/StyleSet/DictationInterims.d.ts.map +1 -0
- package/lib/Styles/StyleSet/ErrorBox.d.ts +33 -0
- package/lib/Styles/StyleSet/ErrorBox.d.ts.map +1 -0
- package/lib/Styles/StyleSet/ErrorNotification.d.ts +23 -0
- package/lib/Styles/StyleSet/ErrorNotification.d.ts.map +1 -0
- package/lib/Styles/StyleSet/FileContent.d.ts +32 -0
- package/lib/Styles/StyleSet/FileContent.d.ts.map +1 -0
- package/lib/Styles/StyleSet/ImageAvatar.d.ts +7 -0
- package/lib/Styles/StyleSet/ImageAvatar.d.ts.map +1 -0
- package/lib/Styles/StyleSet/InitialsAvatar.d.ts +19 -0
- package/lib/Styles/StyleSet/InitialsAvatar.d.ts.map +1 -0
- package/lib/Styles/StyleSet/MicrophoneButton.d.ts +13 -0
- package/lib/Styles/StyleSet/MicrophoneButton.d.ts.map +1 -0
- package/lib/Styles/StyleSet/Root.d.ts +8 -0
- package/lib/Styles/StyleSet/Root.d.ts.map +1 -0
- package/lib/Styles/StyleSet/ScrollToEndButton.d.ts +36 -0
- package/lib/Styles/StyleSet/ScrollToEndButton.d.ts.map +1 -0
- package/lib/Styles/StyleSet/ScrollToEndButton.js +36 -34
- package/lib/Styles/StyleSet/SendBox.d.ts +24 -0
- package/lib/Styles/StyleSet/SendBox.d.ts.map +1 -0
- package/lib/Styles/StyleSet/SendBoxButton.d.ts +33 -0
- package/lib/Styles/StyleSet/SendBoxButton.d.ts.map +1 -0
- package/lib/Styles/StyleSet/SendBoxTextBox.d.ts +41 -0
- package/lib/Styles/StyleSet/SendBoxTextBox.d.ts.map +1 -0
- package/lib/Styles/StyleSet/SendStatus.d.ts +8 -0
- package/lib/Styles/StyleSet/SendStatus.d.ts.map +1 -0
- package/lib/Styles/StyleSet/SingleAttachmentActivity.d.ts +11 -0
- package/lib/Styles/StyleSet/SingleAttachmentActivity.d.ts.map +1 -0
- package/lib/Styles/StyleSet/SpinnerAnimation.d.ts +15 -0
- package/lib/Styles/StyleSet/SpinnerAnimation.d.ts.map +1 -0
- package/lib/Styles/StyleSet/StackedLayout.d.ts +63 -0
- package/lib/Styles/StyleSet/StackedLayout.d.ts.map +1 -0
- package/lib/Styles/StyleSet/SuggestedAction.d.ts +49 -0
- package/lib/Styles/StyleSet/SuggestedAction.d.ts.map +1 -0
- package/lib/Styles/StyleSet/SuggestedAction.js +2 -2
- package/lib/Styles/StyleSet/SuggestedActions.d.ts +118 -0
- package/lib/Styles/StyleSet/SuggestedActions.d.ts.map +1 -0
- package/lib/Styles/StyleSet/TextContent.d.ts +28 -0
- package/lib/Styles/StyleSet/TextContent.d.ts.map +1 -0
- package/lib/Styles/StyleSet/Toast.d.ts +65 -0
- package/lib/Styles/StyleSet/Toast.d.ts.map +1 -0
- package/lib/Styles/StyleSet/Toaster.d.ts +111 -0
- package/lib/Styles/StyleSet/Toaster.d.ts.map +1 -0
- package/lib/Styles/StyleSet/TypingAnimation.d.ts +8 -0
- package/lib/Styles/StyleSet/TypingAnimation.d.ts.map +1 -0
- package/lib/Styles/StyleSet/TypingIndicator.d.ts +11 -0
- package/lib/Styles/StyleSet/TypingIndicator.d.ts.map +1 -0
- package/lib/Styles/StyleSet/UploadButton.d.ts +14 -0
- package/lib/Styles/StyleSet/UploadButton.d.ts.map +1 -0
- package/lib/Styles/StyleSet/VideoAttachment.d.ts +2 -0
- package/lib/Styles/StyleSet/VideoAttachment.d.ts.map +1 -0
- package/lib/Styles/StyleSet/VideoContent.d.ts +6 -0
- package/lib/Styles/StyleSet/VideoContent.d.ts.map +1 -0
- package/lib/Styles/StyleSet/VimeoContent.d.ts +7 -0
- package/lib/Styles/StyleSet/VimeoContent.d.ts.map +1 -0
- package/lib/Styles/StyleSet/WarningNotification.d.ts +22 -0
- package/lib/Styles/StyleSet/WarningNotification.d.ts.map +1 -0
- package/lib/Styles/StyleSet/YouTubeContent.d.ts +7 -0
- package/lib/Styles/StyleSet/YouTubeContent.d.ts.map +1 -0
- package/lib/Styles/createStyleSet.d.ts +1103 -0
- package/lib/Styles/createStyleSet.d.ts.map +1 -0
- package/lib/Styles/createStyleSet.js +44 -41
- package/lib/Styles/mirrorStyle.js +2 -2
- package/lib/Toast/CollapseIcon.js +3 -1
- package/lib/Toast/DismissIcon.js +3 -1
- package/lib/Toast/ExpandIcon.js +3 -1
- package/lib/Toast/NotificationIcon.js +1 -1
- package/lib/Toast/createToastMiddleware.d.ts +4 -0
- package/lib/Toast/createToastMiddleware.d.ts.map +1 -0
- package/lib/Toast/createToastMiddleware.js +2 -2
- package/lib/Utils/AccessKeySink/Surface.js +7 -5
- package/lib/Utils/AccessibleButton.js +6 -4
- package/lib/Utils/AccessibleInputText.d.ts +21 -0
- package/lib/Utils/AccessibleInputText.d.ts.map +1 -0
- package/lib/Utils/AccessibleInputText.js +29 -25
- package/lib/Utils/AccessibleTextArea.d.ts +20 -0
- package/lib/Utils/AccessibleTextArea.d.ts.map +1 -0
- package/lib/Utils/AccessibleTextArea.js +35 -24
- package/lib/Utils/CroppedImage.js +2 -2
- package/lib/Utils/Fade.js +2 -2
- package/lib/Utils/FocusRedirector.js +3 -3
- package/lib/Utils/InlineMarkdown.js +6 -6
- package/lib/Utils/TypeFocusSink/FocusBox.js +6 -4
- package/lib/Utils/TypeFocusSink/getTabIndex.d.ts +2 -0
- package/lib/Utils/TypeFocusSink/getTabIndex.d.ts.map +1 -0
- package/lib/Utils/TypeFocusSink/getTabIndex.js +1 -1
- package/lib/Utils/TypeFocusSink/navigableEvent.js +1 -1
- package/lib/Utils/activityAltText.js +100 -0
- package/lib/Utils/addTargetBlankToHyperlinksMarkdown.js +1 -1
- package/lib/Utils/createCustomEvent.js +1 -1
- package/lib/Utils/debounce.js +1 -1
- package/lib/Utils/detectBrowser.js +1 -1
- package/lib/Utils/downscaleImageToDataURL/downscaleImageToDataURLUsingWorker.js +2 -2
- package/lib/Utils/downscaleImageToDataURL/index.js +2 -2
- package/lib/Utils/filterMap.js +1 -1
- package/lib/Utils/findLastIndex.js +2 -2
- package/lib/Utils/mapMap.js +1 -1
- package/lib/Utils/readDataURIToBlob.js +2 -2
- package/lib/Utils/singleToArray.js +1 -1
- package/lib/connectToWebChat.js +5 -3
- package/lib/hooks/index.d.ts +21 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/index.js +1 -1
- package/lib/hooks/internal/BypassSpeechSynthesisPonyfill.js +97 -39
- package/lib/hooks/internal/UITracker.js +2 -2
- package/lib/hooks/internal/useAcknowledgedActivity.js +2 -2
- package/lib/hooks/internal/useDispatchScrollPosition.js +1 -1
- package/lib/hooks/internal/useDispatchTranscriptFocus.js +1 -1
- package/lib/hooks/internal/useEnterKeyHint.js +1 -1
- package/lib/hooks/internal/useForceRender.js +2 -2
- package/lib/hooks/internal/useForceRenderAtInterval.js +2 -2
- package/lib/hooks/internal/useInternalRenderMarkdownInline.js +1 -1
- package/lib/hooks/internal/useLocalizeAccessKey.js +2 -2
- package/lib/hooks/internal/useMemoize.js +2 -2
- package/lib/hooks/internal/useNavigatorPlatform.js +1 -1
- package/lib/hooks/internal/useNonce.js +1 -1
- package/lib/hooks/internal/useRegisterFocusSendBox.js +1 -1
- package/lib/hooks/internal/useRegisterFocusTranscript.js +1 -1
- package/lib/hooks/internal/useRegisterScrollRelative.js +1 -1
- package/lib/hooks/internal/useRegisterScrollTo.js +1 -1
- package/lib/hooks/internal/useRegisterScrollToEnd.js +1 -1
- package/lib/hooks/internal/useReplaceEmoticon.js +2 -2
- package/lib/hooks/internal/useResumeAudioContext.js +33 -0
- package/lib/hooks/internal/useScrollRelative.js +1 -1
- package/lib/hooks/internal/useSettableDictateAbortable.js +1 -1
- package/lib/hooks/internal/useSuggestedActionsAccessKey.js +1 -1
- package/lib/hooks/internal/useUniqueId.d.ts +2 -0
- package/lib/hooks/internal/useUniqueId.d.ts.map +1 -0
- package/lib/hooks/internal/useUniqueId.js +1 -1
- package/lib/hooks/useDictateAbortable.d.ts +2 -0
- package/lib/hooks/useDictateAbortable.d.ts.map +1 -0
- package/lib/hooks/useDictateAbortable.js +2 -2
- package/lib/hooks/useFocus.d.ts +2 -0
- package/lib/hooks/useFocus.d.ts.map +1 -0
- package/lib/hooks/useFocus.js +1 -1
- package/lib/hooks/useFocusSendBox.d.ts +3 -0
- package/lib/hooks/useFocusSendBox.d.ts.map +1 -0
- package/lib/hooks/useFocusSendBox.js +2 -1
- package/lib/hooks/useObserveScrollPosition.d.ts +3 -0
- package/lib/hooks/useObserveScrollPosition.d.ts.map +1 -0
- package/lib/hooks/useObserveScrollPosition.js +2 -2
- package/lib/hooks/useObserveTranscriptFocus.d.ts +5 -0
- package/lib/hooks/useObserveTranscriptFocus.d.ts.map +1 -0
- package/lib/hooks/useObserveTranscriptFocus.js +2 -2
- package/lib/hooks/useRenderMarkdownAsHTML.d.ts +5 -0
- package/lib/hooks/useRenderMarkdownAsHTML.d.ts.map +1 -0
- package/lib/hooks/useRenderMarkdownAsHTML.js +2 -2
- package/lib/hooks/useScrollDown.d.ts +4 -0
- package/lib/hooks/useScrollDown.d.ts.map +1 -0
- package/lib/hooks/useScrollDown.js +1 -1
- package/lib/hooks/useScrollTo.d.ts +5 -0
- package/lib/hooks/useScrollTo.d.ts.map +1 -0
- package/lib/hooks/useScrollTo.js +1 -1
- package/lib/hooks/useScrollToEnd.d.ts +2 -0
- package/lib/hooks/useScrollToEnd.d.ts.map +1 -0
- package/lib/hooks/useScrollToEnd.js +1 -1
- package/lib/hooks/useScrollUp.d.ts +4 -0
- package/lib/hooks/useScrollUp.d.ts.map +1 -0
- package/lib/hooks/useScrollUp.js +1 -1
- package/lib/hooks/useSendFiles.d.ts +2 -0
- package/lib/hooks/useSendFiles.d.ts.map +1 -0
- package/lib/hooks/useSendFiles.js +3 -3
- package/lib/hooks/useStyleSet.d.ts +2 -0
- package/lib/hooks/useStyleSet.d.ts.map +1 -0
- package/lib/hooks/useStyleSet.js +1 -1
- package/lib/hooks/useWebSpeechPonyfill.d.ts +3 -0
- package/lib/hooks/useWebSpeechPonyfill.d.ts.map +1 -0
- package/lib/hooks/useWebSpeechPonyfill.js +1 -1
- package/lib/index.d.ts +209 -22
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +19 -19
- package/lib/tsconfig.json +1 -1
- package/lib/types/ScrollPosition.d.ts +6 -0
- package/lib/types/ScrollPosition.d.ts.map +1 -0
- package/lib/types/ScrollPosition.js +2 -0
- package/package.json +38 -38
- package/src/Activity/{Avatar.js → Avatar.tsx} +9 -2
- package/src/Activity/{Bubble.js → Bubble.tsx} +10 -2
- package/src/Activity/CarouselFilmStrip.js +20 -29
- package/src/Activity/CarouselFilmStripAttachment.js +92 -0
- package/src/Activity/{Speak.js → Speak.tsx} +12 -5
- package/src/Activity/{StackedLayout.js → StackedLayout.tsx} +36 -11
- package/src/Attachment/Assets/DownloadIcon.js +8 -1
- package/src/Attachment/{AudioContent.js → AudioContent.tsx} +12 -3
- package/src/Attachment/{FileContent.js → FileContent.tsx} +10 -7
- package/src/Attachment/{HTMLVideoContent.js → HTMLVideoContent.tsx} +10 -2
- package/src/Attachment/{ImageContent.js → ImageContent.tsx} +7 -2
- package/src/Attachment/{TextContent.js → TextContent.tsx} +14 -7
- package/src/Attachment/{VideoContent.js → VideoContent.tsx} +10 -2
- package/src/Attachment/{VimeoContent.js → VimeoContent.tsx} +15 -8
- package/src/Attachment/{YouTubeContent.js → YouTubeContent.tsx} +12 -5
- package/src/{BasicSendBox.js → BasicSendBox.tsx} +9 -5
- package/src/BasicToaster.js +4 -4
- package/src/BasicTranscript.js +114 -98
- package/src/{BasicTypingIndicator.js → BasicTypingIndicator.tsx} +1 -1
- package/src/{BasicWebChat.js → BasicWebChat.tsx} +13 -4
- package/src/{Composer.js → Composer.tsx} +41 -42
- package/src/Dictation.js +13 -4
- package/src/{ErrorBox.js → ErrorBox.tsx} +7 -2
- package/src/Middleware/Activity/{createCoreMiddleware.js → createCoreMiddleware.tsx} +2 -1
- package/src/Middleware/ActivityStatus/SendStatus/{SendStatus.js → SendStatus.tsx} +8 -3
- package/src/Middleware/ActivityStatus/{Timestamp.js → Timestamp.tsx} +8 -2
- package/src/Middleware/ActivityStatus/{createCoreMiddleware.js → createCoreMiddleware.tsx} +3 -1
- package/src/Middleware/ActivityStatus/createSendStatusMiddleware.js +8 -6
- package/src/Middleware/ActivityStatus/createTimestampMiddleware.js +10 -8
- package/src/Middleware/Attachment/{createCoreMiddleware.js → createCoreMiddleware.tsx} +8 -7
- package/src/Middleware/AttachmentForScreenReader/{createCoreMiddleware.js → createCoreMiddleware.tsx} +4 -3
- package/src/Middleware/Avatar/{createCoreMiddleware.js → createCoreMiddleware.tsx} +10 -3
- package/src/Middleware/CardAction/createCoreMiddleware.js +43 -41
- package/src/Middleware/GroupActivities/createCoreMiddleware.js +6 -4
- package/src/Middleware/ScrollToEndButton/ScrollToEndButton.js +45 -0
- package/src/Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware.ts +17 -0
- package/src/Middleware/Toast/{createCoreMiddleware.js → createCoreMiddleware.tsx} +3 -1
- package/src/Middleware/TypingIndicator/{createCoreMiddleware.js → createCoreMiddleware.tsx} +3 -4
- package/src/{ReactWebChat.js → ReactWebChat.tsx} +25 -7
- package/src/ScreenReaderActivity.js +47 -37
- package/src/SendBox/Assets/AttachmentIcon.js +1 -1
- package/src/SendBox/Assets/MicrophoneIcon.js +1 -1
- package/src/SendBox/{AutoResizeTextArea.js → AutoResizeTextArea.tsx} +30 -4
- package/src/SendBox/{DictationInterims.js → DictationInterims.tsx} +6 -2
- package/src/SendBox/{MicrophoneButton.js → MicrophoneButton.tsx} +35 -25
- package/src/SendBox/{SendButton.js → SendButton.tsx} +8 -3
- package/src/SendBox/SuggestedAction.js +1 -15
- package/src/SendBox/{SuggestedActions.js → SuggestedActions.tsx} +42 -21
- package/src/SendBox/{TextBox.js → TextBox.tsx} +21 -7
- package/src/SendBox/{UploadButton.js → UploadButton.tsx} +7 -3
- package/src/Styles/StyleSet/CarouselFilmStrip.ts +0 -20
- package/src/Styles/StyleSet/CarouselFilmStripAttachment.ts +56 -0
- package/src/Styles/StyleSet/ScrollToEndButton.ts +33 -31
- package/src/Styles/StyleSet/SuggestedAction.ts +1 -1
- package/src/Styles/createStyleSet.ts +41 -39
- package/src/Toast/CollapseIcon.js +9 -1
- package/src/Toast/DismissIcon.js +9 -1
- package/src/Toast/ExpandIcon.js +9 -1
- package/src/Toast/{createToastMiddleware.js → createToastMiddleware.tsx} +3 -2
- package/src/Utils/{AccessibleInputText.js → AccessibleInputText.tsx} +48 -5
- package/src/Utils/{AccessibleTextArea.js → AccessibleTextArea.tsx} +67 -6
- package/src/Utils/TypeFocusSink/FocusBox.js +4 -4
- package/src/Utils/TypeFocusSink/getTabIndex.ts +1 -1
- package/src/Utils/activityAltText.ts +135 -0
- package/src/Utils/findLastIndex.spec.js +2 -0
- package/src/Utils/intersectionOf.spec.js +2 -0
- package/src/Utils/mapMap.spec.js +2 -0
- package/src/Utils/removeInline.spec.js +2 -0
- package/src/Utils/{singleToArray.js → singleToArray.ts} +1 -1
- package/src/Utils/walkMarkdownTokens.spec.js +3 -3
- package/src/hooks/{index.js → index.ts} +1 -0
- package/src/hooks/internal/BypassSpeechSynthesisPonyfill.js +68 -17
- package/src/hooks/internal/useMemoize.spec.js +2 -0
- package/src/hooks/internal/useResumeAudioContext.ts +7 -0
- package/src/hooks/internal/useScrollRelative.js +4 -3
- package/src/hooks/internal/{useUniqueId.js → useUniqueId.ts} +1 -1
- package/src/hooks/{useDictateAbortable.js → useDictateAbortable.ts} +1 -1
- package/src/hooks/{useFocus.js → useFocus.ts} +1 -1
- package/src/hooks/{useFocusSendBox.js → useFocusSendBox.ts} +2 -1
- package/src/hooks/{useObserveScrollPosition.js → useObserveScrollPosition.ts} +6 -1
- package/src/hooks/{useObserveTranscriptFocus.js → useObserveTranscriptFocus.ts} +6 -1
- package/src/hooks/{useRenderMarkdownAsHTML.js → useRenderMarkdownAsHTML.ts} +6 -2
- package/src/hooks/{useScrollDown.js → useScrollDown.ts} +1 -1
- package/src/hooks/{useScrollTo.js → useScrollTo.ts} +5 -1
- package/src/hooks/{useScrollToEnd.js → useScrollToEnd.ts} +1 -1
- package/src/hooks/{useScrollUp.js → useScrollUp.ts} +1 -1
- package/src/hooks/{useSendFiles.js → useSendFiles.ts} +3 -2
- package/src/hooks/{useStyleSet.js → useStyleSet.ts} +1 -1
- package/src/hooks/useWebSpeechPonyfill.ts +7 -0
- package/src/index.ts +7 -11
- package/src/tsconfig.json +1 -1
- package/src/types/ScrollPosition.ts +6 -0
- package/lib/Activity/ScrollToEndButton.js +0 -81
- package/lib/Attachment/Assets/ErrorIcon.js +0 -22
- package/lib/Utils/remarkStripMarkdown.js +0 -26
- package/lib/hooks/internal/useStripMarkdown.js +0 -19
- package/src/Activity/ScrollToEndButton.js +0 -58
- package/src/Attachment/Assets/ErrorIcon.js +0 -9
- package/src/Utils/remarkStripMarkdown.js +0 -13
- package/src/hooks/internal/useStripMarkdown.js +0 -7
- package/src/hooks/useWebSpeechPonyfill.js +0 -5
- package/src/index.tsx +0 -35
|
@@ -2,7 +2,7 @@ import { Constants } from 'botframework-webchat-core';
|
|
|
2
2
|
import { hooks } from 'botframework-webchat-api';
|
|
3
3
|
import classNames from 'classnames';
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
|
-
import React from 'react';
|
|
5
|
+
import React, { FC } from 'react';
|
|
6
6
|
|
|
7
7
|
import DictationInterims from './SendBox/DictationInterims';
|
|
8
8
|
import MicrophoneButton from './SendBox/MicrophoneButton';
|
|
@@ -31,11 +31,11 @@ const ROOT_STYLE = {
|
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
// TODO: [P3] We should consider exposing core/src/definitions and use it instead
|
|
34
|
-
function activityIsSpeakingOrQueuedToSpeak({ channelData: { speak } = {} }) {
|
|
34
|
+
function activityIsSpeakingOrQueuedToSpeak({ channelData: { speak } = {} }: { channelData: { speak?: any } }) {
|
|
35
35
|
return !!speak;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function useSendBoxSpeechInterimsVisible() {
|
|
38
|
+
function useSendBoxSpeechInterimsVisible(): [boolean] {
|
|
39
39
|
const [activities] = useActivities();
|
|
40
40
|
const [dictateState] = useDictateState();
|
|
41
41
|
|
|
@@ -45,10 +45,14 @@ function useSendBoxSpeechInterimsVisible() {
|
|
|
45
45
|
];
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
type BasicSendBoxProps = {
|
|
49
|
+
className?: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const BasicSendBox: FC<BasicSendBoxProps> = ({ className }) => {
|
|
49
53
|
const [{ hideUploadButton, sendBoxButtonAlignment }] = useStyleOptions();
|
|
50
54
|
const [{ sendBox: sendBoxStyleSet }] = useStyleSet();
|
|
51
|
-
const [{ SpeechRecognition } = {}] = useWebSpeechPonyfill();
|
|
55
|
+
const [{ SpeechRecognition = undefined } = {}] = useWebSpeechPonyfill();
|
|
52
56
|
const [direction] = useDirection();
|
|
53
57
|
const [speechInterimsVisible] = useSendBoxSpeechInterimsVisible();
|
|
54
58
|
const styleToEmotionObject = useStyleToEmotionObject();
|
package/src/BasicToaster.js
CHANGED
|
@@ -94,10 +94,10 @@ const BasicToaster = () => {
|
|
|
94
94
|
() => (!expandable || expanded ? `webchat__toaster__list__${instanceId}` : undefined),
|
|
95
95
|
[expandable, expanded, instanceId]
|
|
96
96
|
);
|
|
97
|
-
const headerElementId = useMemo(
|
|
98
|
-
expandable,
|
|
99
|
-
instanceId
|
|
100
|
-
|
|
97
|
+
const headerElementId = useMemo(
|
|
98
|
+
() => (expandable ? `webchat__toaster__header__${instanceId}` : undefined),
|
|
99
|
+
[expandable, instanceId]
|
|
100
|
+
);
|
|
101
101
|
|
|
102
102
|
useEffect(() => {
|
|
103
103
|
!expandable && setExpanded(false);
|
package/src/BasicTranscript.js
CHANGED
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
Composer as ReactScrollToBottomComposer,
|
|
6
6
|
Panel as ReactScrollToBottomPanel,
|
|
7
7
|
useAnimatingToEnd,
|
|
8
|
+
useAtEnd,
|
|
8
9
|
useObserveScrollPosition,
|
|
9
10
|
useScrollTo,
|
|
10
11
|
useScrollToEnd,
|
|
@@ -26,7 +27,6 @@ import isZeroOrPositive from './Utils/isZeroOrPositive';
|
|
|
26
27
|
import removeInline from './Utils/removeInline';
|
|
27
28
|
import ScreenReaderActivity from './ScreenReaderActivity';
|
|
28
29
|
import ScreenReaderText from './ScreenReaderText';
|
|
29
|
-
import ScrollToEndButton from './Activity/ScrollToEndButton';
|
|
30
30
|
import SpeakActivity from './Activity/Speak';
|
|
31
31
|
import tabbableElements from './Utils/tabbableElements';
|
|
32
32
|
import useAcknowledgedActivity from './hooks/internal/useAcknowledgedActivity';
|
|
@@ -47,6 +47,7 @@ const {
|
|
|
47
47
|
useCreateActivityRenderer,
|
|
48
48
|
useCreateActivityStatusRenderer,
|
|
49
49
|
useCreateAvatarRenderer,
|
|
50
|
+
useCreateScrollToEndButtonRenderer,
|
|
50
51
|
useDirection,
|
|
51
52
|
useGroupActivities,
|
|
52
53
|
useLocalizer,
|
|
@@ -86,9 +87,8 @@ function validateAllActivitiesTagged(activities, bins) {
|
|
|
86
87
|
|
|
87
88
|
const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
88
89
|
const [{ basicTranscript: basicTranscriptStyleSet }] = useStyleSet();
|
|
89
|
-
const [
|
|
90
|
-
|
|
91
|
-
] = useStyleOptions();
|
|
90
|
+
const [{ bubbleFromUserNubOffset, bubbleNubOffset, groupTimestamp, internalLiveRegionFadeAfter, showAvatarInGroup }] =
|
|
91
|
+
useStyleOptions();
|
|
92
92
|
const [focusedActivityKey, setFocusedActivityKey] = useState();
|
|
93
93
|
const [activities] = useActivities();
|
|
94
94
|
const [direction] = useDirection();
|
|
@@ -150,9 +150,10 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
150
150
|
[activities]
|
|
151
151
|
);
|
|
152
152
|
|
|
153
|
-
const visibleActivities = useMemo(
|
|
154
|
-
activitiesWithRenderer
|
|
155
|
-
|
|
153
|
+
const visibleActivities = useMemo(
|
|
154
|
+
() => activitiesWithRenderer.map(({ activity }) => activity),
|
|
155
|
+
[activitiesWithRenderer]
|
|
156
|
+
);
|
|
156
157
|
|
|
157
158
|
// Tag activities based on types.
|
|
158
159
|
// The default implementation tag into 2 types: sender and status.
|
|
@@ -255,10 +256,16 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
255
256
|
|
|
256
257
|
const { renderActivity } = activitiesWithRenderer.find(entry => entry.activity === activity);
|
|
257
258
|
const key = getActivityUniqueId(activity) || renderingElements.length;
|
|
259
|
+
const baseAltText =
|
|
260
|
+
typeof activity?.channelData?.['webchat:fallback-text'] === 'string'
|
|
261
|
+
? activity?.channelData?.['webchat:fallback-text']
|
|
262
|
+
: activity?.channelData?.messageBack?.displayText || activity.text;
|
|
263
|
+
|
|
264
|
+
// If "webchat:fallback-text" field is set to empty string, the activity must not be narrated.
|
|
265
|
+
const supportScreenReader = activity?.channelData?.['webchat:fallback-text'] !== '';
|
|
266
|
+
|
|
258
267
|
const {
|
|
259
|
-
|
|
260
|
-
from: { role },
|
|
261
|
-
text
|
|
268
|
+
from: { role }
|
|
262
269
|
} = activity;
|
|
263
270
|
|
|
264
271
|
const topSideNub = role === 'user' ? topSideUserNub : topSideBotNub;
|
|
@@ -342,8 +349,8 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
342
349
|
hideAllTimestamps || indexWithinSenderAndStatusGroup !== activitiesWithSameSenderAndStatus.length - 1,
|
|
343
350
|
key,
|
|
344
351
|
|
|
345
|
-
// When "liveRegionKey" changes, it will show up in the live region momentarily.
|
|
346
|
-
liveRegionKey: key + '|' +
|
|
352
|
+
// When "liveRegionKey" changes or contents that made up the alt text changed, it will show up in the live region momentarily.
|
|
353
|
+
liveRegionKey: key + '|' + baseAltText,
|
|
347
354
|
renderActivity,
|
|
348
355
|
renderActivityStatus,
|
|
349
356
|
renderAvatar,
|
|
@@ -351,7 +358,8 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
351
358
|
|
|
352
359
|
// TODO: [P2] #2858 We should use core/definitions/speakingActivity for this predicate instead
|
|
353
360
|
shouldSpeak: activity.channelData && activity.channelData.speak,
|
|
354
|
-
showCallout
|
|
361
|
+
showCallout,
|
|
362
|
+
supportScreenReader
|
|
355
363
|
});
|
|
356
364
|
});
|
|
357
365
|
});
|
|
@@ -440,6 +448,8 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
440
448
|
[activityElementsRef, rootElementRef, scrollToBottomScrollTo]
|
|
441
449
|
);
|
|
442
450
|
|
|
451
|
+
const scrollToEnd = useCallback(() => scrollToBottomScrollToEnd({ behavior: 'smooth' }), [scrollToBottomScrollToEnd]);
|
|
452
|
+
|
|
443
453
|
const scrollRelative = useCallback(
|
|
444
454
|
(direction, { displacement } = {}) => {
|
|
445
455
|
const { current: rootElement } = rootElementRef;
|
|
@@ -470,7 +480,7 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
470
480
|
// Since there could be multiple instances of <BasicTranscript> inside the <Composer>, when the developer calls `scrollXXX`, we need to call it on all instances.
|
|
471
481
|
// We call `useRegisterScrollXXX` to register a callback function, the `useScrollXXX` will multiplex the call into each instance of <BasicTranscript>.
|
|
472
482
|
useRegisterScrollTo(scrollTo);
|
|
473
|
-
useRegisterScrollToEnd(
|
|
483
|
+
useRegisterScrollToEnd(scrollToEnd);
|
|
474
484
|
useRegisterScrollRelative(scrollRelative);
|
|
475
485
|
|
|
476
486
|
const dispatchScrollPosition = useDispatchScrollPosition();
|
|
@@ -691,9 +701,10 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
691
701
|
[focus]
|
|
692
702
|
);
|
|
693
703
|
|
|
694
|
-
const focusTranscriptCallback = useCallback(
|
|
695
|
-
rootElementRef
|
|
696
|
-
|
|
704
|
+
const focusTranscriptCallback = useCallback(
|
|
705
|
+
() => rootElementRef.current && rootElementRef.current.focus(),
|
|
706
|
+
[rootElementRef]
|
|
707
|
+
);
|
|
697
708
|
|
|
698
709
|
useRegisterFocusTranscript(focusTranscriptCallback);
|
|
699
710
|
|
|
@@ -713,10 +724,10 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
713
724
|
return activity;
|
|
714
725
|
}, [focusedActivityKey, renderingElements]);
|
|
715
726
|
|
|
716
|
-
useMemo(
|
|
717
|
-
dispatchTranscriptFocus,
|
|
718
|
-
focusedActivity
|
|
719
|
-
|
|
727
|
+
useMemo(
|
|
728
|
+
() => dispatchTranscriptFocus && dispatchTranscriptFocus({ activity: focusedActivity }),
|
|
729
|
+
[dispatchTranscriptFocus, focusedActivity]
|
|
730
|
+
);
|
|
720
731
|
|
|
721
732
|
// This is required by IE11.
|
|
722
733
|
// When the user clicks on and empty space (a.k.a. filler) in an empty transcript, IE11 says the focus is on the <div className="filler">,
|
|
@@ -760,11 +771,13 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
760
771
|
aria-roledescription={transcriptRoleDescription}
|
|
761
772
|
role="log"
|
|
762
773
|
>
|
|
763
|
-
{renderingElements
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
774
|
+
{renderingElements
|
|
775
|
+
.filter(({ supportScreenReader }) => supportScreenReader)
|
|
776
|
+
.map(({ activity, liveRegionKey }) => (
|
|
777
|
+
<Fade fadeAfter={internalLiveRegionFadeAfter} key={liveRegionKey}>
|
|
778
|
+
{() => <ScreenReaderActivity activity={activity} />}
|
|
779
|
+
</Fade>
|
|
780
|
+
))}
|
|
768
781
|
</section>
|
|
769
782
|
{/* TODO: [P2] Fix ESLint error `no-use-before-define` */}
|
|
770
783
|
{/* eslint-disable-next-line @typescript-eslint/no-use-before-define */}
|
|
@@ -790,7 +803,8 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
790
803
|
renderAvatar,
|
|
791
804
|
role,
|
|
792
805
|
shouldSpeak,
|
|
793
|
-
showCallout
|
|
806
|
+
showCallout,
|
|
807
|
+
supportScreenReader
|
|
794
808
|
},
|
|
795
809
|
index
|
|
796
810
|
) => {
|
|
@@ -818,9 +832,11 @@ const InternalTranscript = ({ activityElementsRef, className }) => {
|
|
|
818
832
|
onMouseDownCapture={handleMouseDownCapture}
|
|
819
833
|
ref={callbackRef}
|
|
820
834
|
>
|
|
821
|
-
|
|
822
|
-
{
|
|
823
|
-
|
|
835
|
+
{supportScreenReader && (
|
|
836
|
+
<ScreenReaderActivity activity={activity} id={ariaLabelID} renderAttachments={false}>
|
|
837
|
+
{!!isContentInteractive && <p>{activityInteractiveAlt}</p>}
|
|
838
|
+
</ScreenReaderActivity>
|
|
839
|
+
)}
|
|
824
840
|
<FocusRedirector
|
|
825
841
|
className="webchat__basic-transcript__activity-sentinel"
|
|
826
842
|
onFocus={focusActivity}
|
|
@@ -916,19 +932,20 @@ InternalScreenReaderTranscript.propTypes = {
|
|
|
916
932
|
// Separating high-frequency hooks to improve performance.
|
|
917
933
|
const InternalTranscriptScrollable = ({ activities, children, onFocusActivity, onFocusFiller, terminatorRef }) => {
|
|
918
934
|
const [{ activities: activitiesStyleSet }] = useStyleSet();
|
|
919
|
-
const [{ hideScrollToEndButton }] = useStyleOptions();
|
|
920
935
|
const [animatingToEnd] = useAnimatingToEnd();
|
|
936
|
+
const [atEnd] = useAtEnd();
|
|
921
937
|
const [sticky] = useSticky();
|
|
938
|
+
const [styleOptions] = useStyleOptions();
|
|
922
939
|
const lastVisibleActivityId = getActivityUniqueId(activities[activities.length - 1] || {}); // Activity ID of the last visible activity in the list.
|
|
923
940
|
const localize = useLocalizer();
|
|
924
|
-
const
|
|
941
|
+
const scrollToEnd = useScrollToEnd();
|
|
925
942
|
|
|
926
943
|
const lastReadActivityIdRef = useRef(lastVisibleActivityId);
|
|
927
944
|
const transcriptRoleDescription = localize('TRANSCRIPT_ARIA_ROLE_ALT');
|
|
928
945
|
|
|
929
|
-
const allActivitiesRead = lastVisibleActivityId === lastReadActivityIdRef.current;
|
|
930
|
-
|
|
931
946
|
const handleScrollToEndButtonClick = useCallback(() => {
|
|
947
|
+
scrollToEnd({ behavior: 'smooth' });
|
|
948
|
+
|
|
932
949
|
// After the "New message" button is clicked, focus on the first unread activity.
|
|
933
950
|
const index = activities.findIndex(({ id }) => id === lastReadActivityIdRef.current);
|
|
934
951
|
|
|
@@ -943,49 +960,29 @@ const InternalTranscriptScrollable = ({ activities, children, onFocusActivity, o
|
|
|
943
960
|
const { current } = terminatorRef;
|
|
944
961
|
|
|
945
962
|
current && current.focus();
|
|
946
|
-
}, [activities, lastReadActivityIdRef, onFocusActivity, terminatorRef]);
|
|
963
|
+
}, [activities, lastReadActivityIdRef, onFocusActivity, scrollToEnd, terminatorRef]);
|
|
947
964
|
|
|
948
|
-
if (sticky) {
|
|
949
|
-
// If it is sticky, the user is at the bottom of the transcript, everything is read.
|
|
965
|
+
if (atEnd || sticky) {
|
|
966
|
+
// If it is sticky or at the end, the user is at the bottom of the transcript, everything is read.
|
|
950
967
|
// So mark the activity ID as read.
|
|
951
968
|
lastReadActivityIdRef.current = lastVisibleActivityId;
|
|
952
969
|
}
|
|
953
970
|
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
// - All activities have been read
|
|
958
|
-
// - Currently animating towards bottom
|
|
959
|
-
// - "New messages" button must not flash when: 1. Type "help", 2. Scroll to top, 3. Type "help" again, 4. Expect the "New messages" button not flashy
|
|
960
|
-
// - Hidden by style options
|
|
961
|
-
// - It is already at the bottom (sticky)
|
|
962
|
-
|
|
963
|
-
// Any changes to this logic, verify:
|
|
964
|
-
// - "New messages" button should persist while programmatically scrolling to mid-point of the transcript:
|
|
965
|
-
// 1. Type "help"
|
|
966
|
-
// 2. Type "proactive", then immediately scroll to top
|
|
967
|
-
// Expect: the "New messages" button should appear
|
|
968
|
-
// 3. Run hook "useScrollTo({ scrollTop: 500 })"
|
|
969
|
-
// Expect: when the scroll is animating to 500px, the "New messages" button should kept on the screen
|
|
970
|
-
// - "New messages" button must not flashy:
|
|
971
|
-
// 1. Type "help"
|
|
972
|
-
// 2. Scroll to top
|
|
973
|
-
// Expect: no "New messages" button is shown
|
|
974
|
-
// 3. Type "help" again
|
|
975
|
-
// Expect: "New messages" button must not flash-appear
|
|
976
|
-
|
|
977
|
-
if (allActivitiesRead || animatingToEnd || hideScrollToEndButton || sticky) {
|
|
978
|
-
return -1;
|
|
979
|
-
}
|
|
971
|
+
const ScrollToEndButton = useCreateScrollToEndButtonRenderer()({
|
|
972
|
+
atEnd: animatingToEnd || atEnd || sticky,
|
|
973
|
+
styleOptions,
|
|
980
974
|
|
|
981
|
-
|
|
982
|
-
|
|
975
|
+
// Unread means:
|
|
976
|
+
// 1. Last read is not the last one in the transcript, and;
|
|
977
|
+
// 2. Last read is still in the transcript.
|
|
978
|
+
unread:
|
|
979
|
+
lastVisibleActivityId !== lastReadActivityIdRef.current &&
|
|
980
|
+
!!~activities.findIndex(activity => getActivityUniqueId(activity) === lastReadActivityIdRef.current)
|
|
981
|
+
});
|
|
983
982
|
|
|
984
983
|
return (
|
|
985
984
|
<React.Fragment>
|
|
986
|
-
{
|
|
987
|
-
<ScrollToEndButton onClick={handleScrollToEndButtonClick} ref={scrollToEndButtonRef} />
|
|
988
|
-
)}
|
|
985
|
+
{ScrollToEndButton && <ScrollToEndButton onClick={handleScrollToEndButtonClick} />}
|
|
989
986
|
{!!React.Children.count(children) && (
|
|
990
987
|
<FocusRedirector className="webchat__basic-transcript__sentinel" redirectRef={terminatorRef} />
|
|
991
988
|
)}
|
|
@@ -1016,10 +1013,13 @@ const SetScroller = ({ activityElementsRef, scrollerRef }) => {
|
|
|
1016
1013
|
const [
|
|
1017
1014
|
{ autoScrollSnapOnActivity, autoScrollSnapOnActivityOffset, autoScrollSnapOnPage, autoScrollSnapOnPageOffset }
|
|
1018
1015
|
] = useStyleOptions();
|
|
1016
|
+
const [activities] = useActivities();
|
|
1019
1017
|
const [lastAcknowledgedActivity] = useAcknowledgedActivity();
|
|
1020
1018
|
|
|
1019
|
+
const activitiesRef = useRef(activities);
|
|
1021
1020
|
const lastAcknowledgedActivityRef = useRef(lastAcknowledgedActivity);
|
|
1022
1021
|
|
|
1022
|
+
activitiesRef.current = activities;
|
|
1023
1023
|
lastAcknowledgedActivityRef.current = lastAcknowledgedActivity;
|
|
1024
1024
|
|
|
1025
1025
|
scrollerRef.current = useCallback(
|
|
@@ -1042,41 +1042,56 @@ const SetScroller = ({ activityElementsRef, scrollerRef }) => {
|
|
|
1042
1042
|
typeof autoScrollSnapOnPageOffset === 'number' ? autoScrollSnapOnPageOffset : 0;
|
|
1043
1043
|
|
|
1044
1044
|
if (patchedAutoScrollSnapOnActivity || patchedAutoScrollSnapOnPage) {
|
|
1045
|
+
const { current: activities } = activitiesRef;
|
|
1046
|
+
const { current: activityElements } = activityElementsRef;
|
|
1045
1047
|
const { current: lastAcknowledgedActivity } = lastAcknowledgedActivityRef;
|
|
1046
|
-
|
|
1047
1048
|
const values = [];
|
|
1048
1049
|
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1050
|
+
const lastAcknowledgedActivityIndex = activities.indexOf(lastAcknowledgedActivity);
|
|
1051
|
+
|
|
1052
|
+
if (~lastAcknowledgedActivityIndex) {
|
|
1053
|
+
// The activity that we acknowledged could be not rendered, such as post back activity.
|
|
1054
|
+
// When calculating scroll snap, we can only base on the first unacknowledged-and-rendering activity.
|
|
1055
|
+
let firstUnacknowledgedActivityElementIndex = -1;
|
|
1056
|
+
|
|
1057
|
+
for (let index = lastAcknowledgedActivityIndex + 1, { length } = activities; index < length; index++) {
|
|
1058
|
+
const activity = activities[index];
|
|
1059
|
+
const activityElementIndex = activityElements.findIndex(entry => entry.activity === activity);
|
|
1060
|
+
|
|
1061
|
+
if (~activityElementIndex) {
|
|
1062
|
+
firstUnacknowledgedActivityElementIndex = activityElementIndex;
|
|
1063
|
+
break;
|
|
1064
|
+
}
|
|
1064
1065
|
}
|
|
1065
|
-
}
|
|
1066
1066
|
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1067
|
+
if (~firstUnacknowledgedActivityElementIndex) {
|
|
1068
|
+
if (patchedAutoScrollSnapOnActivity) {
|
|
1069
|
+
// Gets the activity element which we should snap to.
|
|
1070
|
+
const { element: nthUnacknowledgedActivityElement } =
|
|
1071
|
+
activityElements[firstUnacknowledgedActivityElementIndex + patchedAutoScrollSnapOnActivity - 1];
|
|
1072
|
+
|
|
1073
|
+
if (nthUnacknowledgedActivityElement) {
|
|
1074
|
+
values.push(
|
|
1075
|
+
nthUnacknowledgedActivityElement.offsetTop +
|
|
1076
|
+
nthUnacknowledgedActivityElement.offsetHeight -
|
|
1077
|
+
offsetHeight -
|
|
1078
|
+
scrollTop +
|
|
1079
|
+
patchedAutoScrollSnapOnActivityOffset
|
|
1080
|
+
);
|
|
1081
|
+
}
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
if (patchedAutoScrollSnapOnPage) {
|
|
1085
|
+
const { element: firstUnacknowledgedActivityElement } =
|
|
1086
|
+
activityElements[firstUnacknowledgedActivityElementIndex];
|
|
1087
|
+
|
|
1088
|
+
values.push(
|
|
1089
|
+
firstUnacknowledgedActivityElement.offsetTop -
|
|
1090
|
+
scrollTop -
|
|
1091
|
+
offsetHeight * (1 - patchedAutoScrollSnapOnPage) +
|
|
1092
|
+
patchedAutoScrollSnapOnPageOffset
|
|
1093
|
+
);
|
|
1094
|
+
}
|
|
1080
1095
|
}
|
|
1081
1096
|
}
|
|
1082
1097
|
|
|
@@ -1086,6 +1101,7 @@ const SetScroller = ({ activityElementsRef, scrollerRef }) => {
|
|
|
1086
1101
|
return Infinity;
|
|
1087
1102
|
},
|
|
1088
1103
|
[
|
|
1104
|
+
activitiesRef,
|
|
1089
1105
|
activityElementsRef,
|
|
1090
1106
|
autoScrollSnapOnActivity,
|
|
1091
1107
|
autoScrollSnapOnActivityOffset,
|
|
@@ -2,7 +2,7 @@ import { hooks } from 'botframework-webchat-api';
|
|
|
2
2
|
|
|
3
3
|
const { useActiveTyping, useRenderTypingIndicator } = hooks;
|
|
4
4
|
|
|
5
|
-
function useTypingIndicatorVisible() {
|
|
5
|
+
function useTypingIndicatorVisible(): [boolean] {
|
|
6
6
|
const [activeTyping] = useActiveTyping();
|
|
7
7
|
|
|
8
8
|
return [!!Object.values(activeTyping).filter(({ role }) => role !== 'user').length];
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { hooks } from 'botframework-webchat-api';
|
|
5
5
|
import classNames from 'classnames';
|
|
6
6
|
import PropTypes from 'prop-types';
|
|
7
|
-
import React from 'react';
|
|
7
|
+
import React, { FC } from 'react';
|
|
8
8
|
|
|
9
9
|
import AccessKeySinkSurface from './Utils/AccessKeySink/Surface';
|
|
10
10
|
import BasicConnectivityStatus from './BasicConnectivityStatus';
|
|
@@ -40,7 +40,12 @@ const TRANSCRIPT_STYLE = {
|
|
|
40
40
|
// Subset of landmark roles: https://w3.org/TR/wai-aria/#landmark_roles
|
|
41
41
|
const ARIA_LANDMARK_ROLES = ['complementary', 'contentinfo', 'form', 'main', 'region'];
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
type BasicWebChatProps = {
|
|
44
|
+
className?: string;
|
|
45
|
+
role?: 'complementary' | 'contentinfo' | 'form' | 'main' | 'region';
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const BasicWebChat: FC<BasicWebChatProps> = ({ className, role }) => {
|
|
44
49
|
const [{ root: rootStyleSet }] = useStyleSet();
|
|
45
50
|
const [options] = useStyleOptions();
|
|
46
51
|
const styleToEmotionObject = useStyleToEmotionObject();
|
|
@@ -66,8 +71,6 @@ const BasicWebChat = ({ className, role }) => {
|
|
|
66
71
|
);
|
|
67
72
|
};
|
|
68
73
|
|
|
69
|
-
export default BasicWebChat;
|
|
70
|
-
|
|
71
74
|
BasicWebChat.defaultProps = {
|
|
72
75
|
className: '',
|
|
73
76
|
role: 'complementary'
|
|
@@ -75,5 +78,11 @@ BasicWebChat.defaultProps = {
|
|
|
75
78
|
|
|
76
79
|
BasicWebChat.propTypes = {
|
|
77
80
|
className: PropTypes.string,
|
|
81
|
+
// Ignoring deficiencies with TypeScript/PropTypes inference.
|
|
82
|
+
// @ts-ignore
|
|
78
83
|
role: PropTypes.oneOf(ARIA_LANDMARK_ROLES)
|
|
79
84
|
};
|
|
85
|
+
|
|
86
|
+
export default BasicWebChat;
|
|
87
|
+
|
|
88
|
+
export type { BasicWebChatProps };
|
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Composer as APIComposer,
|
|
3
|
+
ComposerProps as APIComposerProps,
|
|
4
|
+
hooks,
|
|
5
|
+
WebSpeechPonyfillFactory
|
|
6
|
+
} from 'botframework-webchat-api';
|
|
2
7
|
import { Composer as SayComposer } from 'react-say';
|
|
3
|
-
import
|
|
8
|
+
import { singleToArray } from 'botframework-webchat-core';
|
|
9
|
+
import createEmotion from '@emotion/css/create-instance';
|
|
4
10
|
import createStyleSet from './Styles/createStyleSet';
|
|
5
11
|
import MarkdownIt from 'markdown-it';
|
|
6
12
|
import PropTypes from 'prop-types';
|
|
7
|
-
import React, { useCallback, useMemo, useRef, useState } from 'react';
|
|
13
|
+
import React, { FC, ReactNode, useCallback, useMemo, useRef, useState } from 'react';
|
|
8
14
|
|
|
9
15
|
import {
|
|
10
16
|
speechSynthesis as bypassSpeechSynthesis,
|
|
@@ -18,13 +24,13 @@ import createDefaultAttachmentForScreenReaderMiddleware from './Middleware/Attac
|
|
|
18
24
|
import createDefaultAttachmentMiddleware from './Middleware/Attachment/createCoreMiddleware';
|
|
19
25
|
import createDefaultAvatarMiddleware from './Middleware/Avatar/createCoreMiddleware';
|
|
20
26
|
import createDefaultCardActionMiddleware from './Middleware/CardAction/createCoreMiddleware';
|
|
27
|
+
import createDefaultScrollToEndButtonMiddleware from './Middleware/ScrollToEndButton/createScrollToEndButtonMiddleware';
|
|
21
28
|
import createDefaultToastMiddleware from './Middleware/Toast/createCoreMiddleware';
|
|
22
29
|
import createDefaultTypingIndicatorMiddleware from './Middleware/TypingIndicator/createCoreMiddleware';
|
|
23
30
|
import Dictation from './Dictation';
|
|
24
31
|
import downscaleImageToDataURL from './Utils/downscaleImageToDataURL';
|
|
25
32
|
import ErrorBox from './ErrorBox';
|
|
26
33
|
import mapMap from './Utils/mapMap';
|
|
27
|
-
import singleToArray from './Utils/singleToArray';
|
|
28
34
|
import UITracker from './hooks/internal/UITracker';
|
|
29
35
|
import WebChatUIContext from './hooks/internal/WebChatUIContext';
|
|
30
36
|
|
|
@@ -39,7 +45,17 @@ function styleSetToEmotionObjects(styleToEmotionObject, styleSet) {
|
|
|
39
45
|
return mapMap(styleSet, (style, key) => (key === 'options' ? style : styleToEmotionObject(style)));
|
|
40
46
|
}
|
|
41
47
|
|
|
42
|
-
|
|
48
|
+
type ComposerCoreProps = {
|
|
49
|
+
children?: ReactNode;
|
|
50
|
+
extraStyleSet?: any;
|
|
51
|
+
nonce?: string;
|
|
52
|
+
renderMarkdown?: (markdown: string, { markdownRespectCRLF: boolean }, { externalLinkAlt: string }) => string;
|
|
53
|
+
styleSet?: any;
|
|
54
|
+
suggestedActionsAccessKey?: boolean | string;
|
|
55
|
+
webSpeechPonyfillFactory?: WebSpeechPonyfillFactory;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
const ComposerCore: FC<ComposerCoreProps> = ({
|
|
43
59
|
children,
|
|
44
60
|
extraStyleSet,
|
|
45
61
|
nonce,
|
|
@@ -226,7 +242,13 @@ ComposerCore.propTypes = {
|
|
|
226
242
|
webSpeechPonyfillFactory: PropTypes.func
|
|
227
243
|
};
|
|
228
244
|
|
|
229
|
-
|
|
245
|
+
type ComposerProps = APIComposerProps &
|
|
246
|
+
ComposerCoreProps & {
|
|
247
|
+
nonce?: string;
|
|
248
|
+
webSpeechPonyfillFactory?: WebSpeechPonyfillFactory;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
const Composer: FC<ComposerProps> = ({
|
|
230
252
|
activityMiddleware,
|
|
231
253
|
activityStatusMiddleware,
|
|
232
254
|
attachmentForScreenReaderMiddleware,
|
|
@@ -236,6 +258,7 @@ const Composer = ({
|
|
|
236
258
|
children,
|
|
237
259
|
extraStyleSet,
|
|
238
260
|
renderMarkdown,
|
|
261
|
+
scrollToEndButtonMiddleware,
|
|
239
262
|
styleSet,
|
|
240
263
|
suggestedActionsAccessKey,
|
|
241
264
|
toastMiddleware,
|
|
@@ -287,6 +310,13 @@ const Composer = ({
|
|
|
287
310
|
[typingIndicatorMiddleware]
|
|
288
311
|
);
|
|
289
312
|
|
|
313
|
+
const defaultScrollToEndButtonMiddleware = useMemo(() => createDefaultScrollToEndButtonMiddleware(), []);
|
|
314
|
+
|
|
315
|
+
const patchedScrollToEndButtonMiddleware = useMemo(
|
|
316
|
+
() => [...singleToArray(scrollToEndButtonMiddleware), ...defaultScrollToEndButtonMiddleware],
|
|
317
|
+
[defaultScrollToEndButtonMiddleware, scrollToEndButtonMiddleware]
|
|
318
|
+
);
|
|
319
|
+
|
|
290
320
|
return (
|
|
291
321
|
<React.Fragment>
|
|
292
322
|
<APIComposer
|
|
@@ -300,6 +330,7 @@ const Composer = ({
|
|
|
300
330
|
// Under dev server of create-react-app, "NODE_ENV" will be set to "development".
|
|
301
331
|
internalErrorBoxClass={node_env === 'development' ? ErrorBox : undefined}
|
|
302
332
|
nonce={nonce}
|
|
333
|
+
scrollToEndButtonMiddleware={patchedScrollToEndButtonMiddleware}
|
|
303
334
|
toastMiddleware={patchedToastMiddleware}
|
|
304
335
|
typingIndicatorMiddleware={patchedTypingIndicatorMiddleware}
|
|
305
336
|
{...composerProps}
|
|
@@ -323,47 +354,15 @@ const Composer = ({
|
|
|
323
354
|
Composer.defaultProps = {
|
|
324
355
|
...APIComposer.defaultProps,
|
|
325
356
|
...ComposerCore.defaultProps,
|
|
326
|
-
|
|
327
|
-
activityRenderer: undefined,
|
|
328
|
-
activityStatusMiddleware: undefined,
|
|
329
|
-
activityStatusRenderer: undefined,
|
|
330
|
-
attachmentForScreenReaderMiddleware: undefined,
|
|
331
|
-
attachmentMiddleware: undefined,
|
|
332
|
-
attachmentRenderer: undefined,
|
|
333
|
-
avatarMiddleware: undefined,
|
|
334
|
-
avatarRenderer: undefined,
|
|
335
|
-
cardActionMiddleware: undefined,
|
|
336
|
-
children: undefined,
|
|
337
|
-
nonce: undefined,
|
|
338
|
-
renderMarkdown: undefined,
|
|
339
|
-
toastMiddleware: undefined,
|
|
340
|
-
toastRenderer: undefined,
|
|
341
|
-
typingIndicatorMiddleware: undefined,
|
|
342
|
-
typingIndicatorRenderer: undefined,
|
|
343
|
-
webSpeechPonyfillFactory: undefined
|
|
357
|
+
children: undefined
|
|
344
358
|
};
|
|
345
359
|
|
|
346
360
|
Composer.propTypes = {
|
|
347
361
|
...APIComposer.propTypes,
|
|
348
362
|
...ComposerCore.propTypes,
|
|
349
|
-
|
|
350
|
-
activityRenderer: PropTypes.func,
|
|
351
|
-
activityStatusMiddleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]),
|
|
352
|
-
activityStatusRenderer: PropTypes.func,
|
|
353
|
-
attachmentForScreenReaderMiddleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]),
|
|
354
|
-
attachmentMiddleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]),
|
|
355
|
-
attachmentRenderer: PropTypes.func,
|
|
356
|
-
avatarMiddleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]),
|
|
357
|
-
avatarRenderer: PropTypes.func,
|
|
358
|
-
cardActionMiddleware: PropTypes.func,
|
|
359
|
-
children: PropTypes.any,
|
|
360
|
-
nonce: PropTypes.string,
|
|
361
|
-
renderMarkdown: PropTypes.func,
|
|
362
|
-
toastMiddleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]),
|
|
363
|
-
toastRenderer: PropTypes.func,
|
|
364
|
-
typingIndicatorMiddleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]),
|
|
365
|
-
typingIndicatorRenderer: PropTypes.func,
|
|
366
|
-
webSpeechPonyfillFactory: PropTypes.func
|
|
363
|
+
children: PropTypes.any
|
|
367
364
|
};
|
|
368
365
|
|
|
369
366
|
export default Composer;
|
|
367
|
+
|
|
368
|
+
export type { ComposerProps };
|