botframework-webchat-api 4.14.1 → 4.15.2-main.20220413.af6e8a3
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/.eslintrc.yml +4 -105
- package/.prettierrc.yml +1 -1
- package/lib/StyleOptions.d.ts +244 -14
- package/lib/StyleOptions.d.ts.map +1 -1
- package/lib/defaultStyleOptions.d.ts.map +1 -1
- package/lib/defaultStyleOptions.js +67 -14
- package/lib/hooks/Composer.d.ts +3 -3
- package/lib/hooks/Composer.d.ts.map +1 -1
- package/lib/hooks/Composer.js +29 -11
- package/lib/hooks/index.d.ts +11 -1
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/index.js +81 -1
- package/lib/hooks/internal/WebChatAPIContext.d.ts +3 -3
- package/lib/hooks/internal/WebChatAPIContext.d.ts.map +1 -1
- package/lib/hooks/internal/WebChatAPIContext.js +1 -1
- package/lib/hooks/internal/useCreateActivityRendererInternal.d.ts.map +1 -1
- package/lib/hooks/internal/useCreateActivityRendererInternal.js +1 -1
- package/lib/hooks/internal/useDebugDeps.js +10 -4
- package/lib/hooks/internal/usePrevious.d.ts +2 -0
- package/lib/hooks/internal/usePrevious.d.ts.map +1 -0
- package/lib/hooks/internal/usePrevious.js +17 -0
- package/lib/hooks/internal/useReadTelemetryDimensions.js +2 -2
- package/lib/hooks/internal/useValueRef.d.ts +3 -0
- package/lib/hooks/internal/useValueRef.d.ts.map +1 -0
- package/lib/hooks/internal/useValueRef.js +24 -0
- package/lib/hooks/middleware/UserlandBoundary.js +1 -1
- package/lib/hooks/middleware/applyMiddleware.js +1 -1
- package/lib/hooks/middleware/concatMiddleware.d.ts.map +1 -1
- package/lib/hooks/middleware/concatMiddleware.js +2 -2
- package/lib/hooks/middleware/createDefaultCardActionMiddleware.d.ts.map +1 -1
- package/lib/hooks/middleware/createDefaultCardActionMiddleware.js +1 -1
- package/lib/hooks/middleware/createDefaultGroupActivitiesMiddleware.d.ts.map +1 -1
- package/lib/hooks/middleware/createDefaultGroupActivitiesMiddleware.js +19 -3
- package/lib/hooks/useActiveTyping.d.ts.map +1 -1
- package/lib/hooks/useActiveTyping.js +5 -4
- package/lib/hooks/useActivities.d.ts +2 -2
- package/lib/hooks/useActivities.d.ts.map +1 -1
- package/lib/hooks/useActivities.js +1 -1
- package/lib/hooks/useActivityKeys.d.ts +3 -0
- package/lib/hooks/useActivityKeys.d.ts.map +1 -0
- package/lib/hooks/useActivityKeys.js +14 -0
- package/lib/hooks/useActivityKeysByRead.d.ts +3 -0
- package/lib/hooks/useActivityKeysByRead.d.ts.map +1 -0
- package/lib/hooks/useActivityKeysByRead.js +14 -0
- package/lib/hooks/useCreateActivityStatusRenderer.d.ts +3 -3
- package/lib/hooks/useCreateActivityStatusRenderer.d.ts.map +1 -1
- package/lib/hooks/useCreateActivityStatusRenderer.js +47 -16
- package/lib/hooks/useCreateAvatarRenderer.d.ts +5 -3
- package/lib/hooks/useCreateAvatarRenderer.d.ts.map +1 -1
- package/lib/hooks/useCreateAvatarRenderer.js +1 -1
- package/lib/hooks/useDateFormatter.d.ts.map +1 -1
- package/lib/hooks/useDateFormatter.js +1 -1
- package/lib/hooks/useDebouncedNotifications.js +3 -3
- package/lib/hooks/useGetActivityByKey.d.ts +3 -0
- package/lib/hooks/useGetActivityByKey.d.ts.map +1 -0
- package/lib/hooks/useGetActivityByKey.js +14 -0
- package/lib/hooks/useGetHasAcknowledgedByActivityKey.d.ts +3 -0
- package/lib/hooks/useGetHasAcknowledgedByActivityKey.d.ts.map +1 -0
- package/lib/hooks/useGetHasAcknowledgedByActivityKey.js +14 -0
- package/lib/hooks/useGetKeyByActivity.d.ts +3 -0
- package/lib/hooks/useGetKeyByActivity.d.ts.map +1 -0
- package/lib/hooks/useGetKeyByActivity.js +14 -0
- package/lib/hooks/useGetKeyByActivityId.d.ts +3 -0
- package/lib/hooks/useGetKeyByActivityId.d.ts.map +1 -0
- package/lib/hooks/useGetKeyByActivityId.js +14 -0
- package/lib/hooks/useGetSendTimeoutForActivity.d.ts +2 -2
- package/lib/hooks/useGetSendTimeoutForActivity.d.ts.map +1 -1
- package/lib/hooks/useGetSendTimeoutForActivity.js +4 -2
- package/lib/hooks/useGroupActivities.d.ts +4 -4
- package/lib/hooks/useGroupActivities.d.ts.map +1 -1
- package/lib/hooks/useGroupActivities.js +1 -1
- package/lib/hooks/useLastAcknowledgedActivityKey.d.ts +3 -0
- package/lib/hooks/useLastAcknowledgedActivityKey.d.ts.map +1 -0
- package/lib/hooks/useLastAcknowledgedActivityKey.js +14 -0
- package/lib/hooks/useLastReadActivityKey.d.ts +3 -0
- package/lib/hooks/useLastReadActivityKey.d.ts.map +1 -0
- package/lib/hooks/useLastReadActivityKey.js +14 -0
- package/lib/hooks/useLocalizer.d.ts +1 -1
- package/lib/hooks/useLocalizer.d.ts.map +1 -1
- package/lib/hooks/useLocalizer.js +9 -3
- package/lib/hooks/useMarkActivityAsSpoken.d.ts +2 -2
- package/lib/hooks/useMarkActivityAsSpoken.d.ts.map +1 -1
- package/lib/hooks/useMarkActivityAsSpoken.js +1 -1
- package/lib/hooks/useMarkActivityKeyAsRead.d.ts +3 -0
- package/lib/hooks/useMarkActivityKeyAsRead.d.ts.map +1 -0
- package/lib/hooks/useMarkActivityKeyAsRead.js +14 -0
- package/lib/hooks/useMarkAllAsAcknowledged.d.ts +3 -0
- package/lib/hooks/useMarkAllAsAcknowledged.d.ts.map +1 -0
- package/lib/hooks/useMarkAllAsAcknowledged.js +14 -0
- package/lib/hooks/usePerformCardAction.d.ts +2 -2
- package/lib/hooks/usePerformCardAction.d.ts.map +1 -1
- package/lib/hooks/usePerformCardAction.js +1 -1
- package/lib/hooks/usePostActivity.d.ts +2 -2
- package/lib/hooks/usePostActivity.d.ts.map +1 -1
- package/lib/hooks/usePostActivity.js +1 -1
- package/lib/hooks/useSendFiles.d.ts +8 -1
- package/lib/hooks/useSendFiles.d.ts.map +1 -1
- package/lib/hooks/useSendFiles.js +1 -1
- package/lib/hooks/useSendTimeoutForActivity.d.ts +2 -2
- package/lib/hooks/useSendTimeoutForActivity.d.ts.map +1 -1
- package/lib/hooks/useSendTimeoutForActivity.js +1 -1
- package/lib/hooks/useSubmitSendBox.d.ts.map +1 -1
- package/lib/hooks/useSubmitSendBox.js +8 -5
- package/lib/hooks/useSuggestedActions.d.ts +1 -1
- package/lib/hooks/useSuggestedActions.d.ts.map +1 -1
- package/lib/hooks/useSuggestedActions.js +1 -1
- package/lib/hooks/useTimeoutForSend.d.ts +2 -2
- package/lib/hooks/useTimeoutForSend.d.ts.map +1 -1
- package/lib/hooks/useTimeoutForSend.js +1 -1
- package/lib/hooks/useTrackException.js +2 -2
- package/lib/hooks/utils/ErrorBoundary.js +4 -4
- package/lib/index.js +8 -8
- package/lib/localization/Localize.d.ts.map +1 -1
- package/lib/localization/Localize.js +12 -6
- package/lib/localization/ar-SA.json +23 -4
- package/lib/localization/bg-BG.json +23 -4
- package/lib/localization/ca-ES.json +23 -4
- package/lib/localization/cs-CZ.json +23 -4
- package/lib/localization/da-DK.json +23 -4
- package/lib/localization/de-DE.json +23 -4
- package/lib/localization/el-GR.json +23 -4
- package/lib/localization/en-US.json +34 -9
- package/lib/localization/es-ES.json +23 -4
- package/lib/localization/et-EE.json +23 -4
- package/lib/localization/eu-ES.json +23 -4
- package/lib/localization/fi-FI.json +23 -4
- package/lib/localization/fr-FR.json +23 -4
- package/lib/localization/gl-ES.json +23 -4
- package/lib/localization/he-IL.json +23 -4
- package/lib/localization/hi-IN.json +23 -4
- package/lib/localization/hr-HR.json +23 -4
- package/lib/localization/hu-HU.json +23 -4
- package/lib/localization/id-ID.json +23 -4
- package/lib/localization/it-IT.json +23 -4
- package/lib/localization/ja-JP.json +23 -4
- package/lib/localization/kk-KZ.json +23 -4
- package/lib/localization/ko-KR.json +23 -4
- package/lib/localization/lt-LT.json +23 -4
- package/lib/localization/lv-LV.json +23 -4
- package/lib/localization/mergeLocalizedStrings.d.ts.map +1 -1
- package/lib/localization/mergeLocalizedStrings.js +13 -6
- package/lib/localization/ms-MY.json +23 -4
- package/lib/localization/nb-NO.json +23 -4
- package/lib/localization/nl-NL.json +23 -4
- package/lib/localization/pl-PL.json +23 -4
- package/lib/localization/pt-BR.json +23 -4
- package/lib/localization/pt-PT.json +23 -4
- package/lib/localization/ro-RO.json +23 -4
- package/lib/localization/ru-RU.json +23 -4
- package/lib/localization/sk-SK.json +23 -4
- package/lib/localization/sl-SI.json +23 -4
- package/lib/localization/sr-Cyrl-CS.json +23 -4
- package/lib/localization/sr-Latn-CS.json +23 -4
- package/lib/localization/sv-SE.json +23 -4
- package/lib/localization/th-TH.json +23 -4
- package/lib/localization/tr-TR.json +23 -4
- package/lib/localization/uk-UA.json +23 -4
- package/lib/localization/vi-VN.json +23 -4
- package/lib/localization/yue.json +26 -7
- package/lib/localization/zh-CN.json +23 -4
- package/lib/localization/zh-HK.json +23 -4
- package/lib/localization/zh-TW.json +23 -4
- package/lib/normalizeStyleOptions.d.ts.map +1 -1
- package/lib/normalizeStyleOptions.js +49 -4
- package/lib/patchStyleOptionsFromDeprecatedProps.js +1 -2
- package/lib/providers/ActivityAcknowledgement/ActivityAcknowledgementComposer.d.ts +5 -0
- package/lib/providers/ActivityAcknowledgement/ActivityAcknowledgementComposer.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/ActivityAcknowledgementComposer.js +184 -0
- package/lib/providers/ActivityAcknowledgement/private/Context.d.ts +13 -0
- package/lib/providers/ActivityAcknowledgement/private/Context.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/private/Context.js +13 -0
- package/lib/providers/ActivityAcknowledgement/private/types.d.ts +6 -0
- package/lib/providers/ActivityAcknowledgement/private/types.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/private/types.js +2 -0
- package/lib/providers/ActivityAcknowledgement/private/useContext.d.ts +3 -0
- package/lib/providers/ActivityAcknowledgement/private/useContext.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/private/useContext.js +24 -0
- package/lib/providers/ActivityAcknowledgement/useActivityKeysByRead.d.ts +5 -0
- package/lib/providers/ActivityAcknowledgement/useActivityKeysByRead.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/useActivityKeysByRead.js +18 -0
- package/lib/providers/ActivityAcknowledgement/useGetHasAcknowledgedByActivityKey.d.ts +2 -0
- package/lib/providers/ActivityAcknowledgement/useGetHasAcknowledgedByActivityKey.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/useGetHasAcknowledgedByActivityKey.js +15 -0
- package/lib/providers/ActivityAcknowledgement/useLastAcknowledgedActivityKey.d.ts +2 -0
- package/lib/providers/ActivityAcknowledgement/useLastAcknowledgedActivityKey.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/useLastAcknowledgedActivityKey.js +15 -0
- package/lib/providers/ActivityAcknowledgement/useLastReadActivityKey.d.ts +2 -0
- package/lib/providers/ActivityAcknowledgement/useLastReadActivityKey.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/useLastReadActivityKey.js +15 -0
- package/lib/providers/ActivityAcknowledgement/useMarkActivityKeyAsRead.d.ts +2 -0
- package/lib/providers/ActivityAcknowledgement/useMarkActivityKeyAsRead.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/useMarkActivityKeyAsRead.js +15 -0
- package/lib/providers/ActivityAcknowledgement/useMarkAllAsAcknowledged.d.ts +2 -0
- package/lib/providers/ActivityAcknowledgement/useMarkAllAsAcknowledged.d.ts.map +1 -0
- package/lib/providers/ActivityAcknowledgement/useMarkAllAsAcknowledged.js +15 -0
- package/lib/providers/ActivityKeyer/ActivityKeyerComposer.d.ts +18 -0
- package/lib/providers/ActivityKeyer/ActivityKeyerComposer.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/ActivityKeyerComposer.js +153 -0
- package/lib/providers/ActivityKeyer/private/Context.d.ts +12 -0
- package/lib/providers/ActivityKeyer/private/Context.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/private/Context.js +13 -0
- package/lib/providers/ActivityKeyer/private/getActivityId.d.ts +3 -0
- package/lib/providers/ActivityKeyer/private/getActivityId.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/private/getActivityId.js +11 -0
- package/lib/providers/ActivityKeyer/private/getClientActivityId.d.ts +3 -0
- package/lib/providers/ActivityKeyer/private/getClientActivityId.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/private/getClientActivityId.js +13 -0
- package/lib/providers/ActivityKeyer/private/uniqueId.d.ts +2 -0
- package/lib/providers/ActivityKeyer/private/uniqueId.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/private/uniqueId.js +18 -0
- package/lib/providers/ActivityKeyer/private/useContext.d.ts +3 -0
- package/lib/providers/ActivityKeyer/private/useContext.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/private/useContext.js +24 -0
- package/lib/providers/ActivityKeyer/useActivityKeys.d.ts +2 -0
- package/lib/providers/ActivityKeyer/useActivityKeys.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/useActivityKeys.js +15 -0
- package/lib/providers/ActivityKeyer/useGetActivityByKey.d.ts +3 -0
- package/lib/providers/ActivityKeyer/useGetActivityByKey.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/useGetActivityByKey.js +15 -0
- package/lib/providers/ActivityKeyer/useGetKeyByActivity.d.ts +3 -0
- package/lib/providers/ActivityKeyer/useGetKeyByActivity.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/useGetKeyByActivity.js +15 -0
- package/lib/providers/ActivityKeyer/useGetKeyByActivityId.d.ts +2 -0
- package/lib/providers/ActivityKeyer/useGetKeyByActivityId.d.ts.map +1 -0
- package/lib/providers/ActivityKeyer/useGetKeyByActivityId.js +15 -0
- package/lib/types/ActivityMiddleware.d.ts +3 -3
- package/lib/types/ActivityMiddleware.d.ts.map +1 -1
- package/lib/types/ActivityStatusMiddleware.d.ts +3 -3
- package/lib/types/ActivityStatusMiddleware.d.ts.map +1 -1
- package/lib/types/AttachmentForScreenReaderMiddleware.d.ts +2 -2
- package/lib/types/AttachmentForScreenReaderMiddleware.d.ts.map +1 -1
- package/lib/types/AttachmentMiddleware.d.ts +2 -2
- package/lib/types/AttachmentMiddleware.d.ts.map +1 -1
- package/lib/types/AvatarMiddleware.d.ts +2 -2
- package/lib/types/AvatarMiddleware.d.ts.map +1 -1
- package/lib/types/CardActionMiddleware.d.ts +4 -2
- package/lib/types/CardActionMiddleware.d.ts.map +1 -1
- package/lib/types/GroupActivitiesMiddleware.d.ts +7 -7
- package/lib/types/GroupActivitiesMiddleware.d.ts.map +1 -1
- package/lib/types/WebSpeechPonyfill.d.ts +1 -0
- package/lib/types/WebSpeechPonyfill.d.ts.map +1 -1
- package/lib/utils/createCustomEvent.d.ts.map +1 -1
- package/lib/utils/createCustomEvent.js +8 -2
- package/lib/utils/findLastIndex.d.ts +2 -0
- package/lib/utils/findLastIndex.d.ts.map +1 -0
- package/lib/utils/findLastIndex.js +32 -0
- package/lib/utils/findMin.js +1 -1
- package/lib/utils/mapMap.d.ts.map +1 -1
- package/lib/utils/mapMap.js +9 -2
- package/lib/utils/randomId.d.ts.map +1 -1
- package/lib/utils/randomId.js +1 -1
- package/package.json +26 -29
- package/src/StyleOptions.ts +295 -14
- package/src/defaultStyleOptions.ts +71 -13
- package/src/hooks/Composer.tsx +90 -54
- package/src/hooks/index.ts +20 -0
- package/src/hooks/internal/WebChatAPIContext.ts +3 -3
- package/src/hooks/internal/useCreateActivityRendererInternal.ts +21 -20
- package/src/hooks/internal/useDebugDeps.js +9 -2
- package/src/hooks/internal/usePrevious.ts +11 -0
- package/src/hooks/internal/useValueRef.ts +21 -0
- package/src/hooks/middleware/concatMiddleware.ts +6 -4
- package/src/hooks/middleware/createDefaultCardActionMiddleware.ts +29 -27
- package/src/hooks/middleware/createDefaultGroupActivitiesMiddleware.ts +18 -6
- package/src/hooks/useActiveTyping.ts +5 -3
- package/src/hooks/useActivities.ts +2 -2
- package/src/hooks/useActivityKeys.ts +3 -0
- package/src/hooks/useActivityKeysByRead.ts +3 -0
- package/src/hooks/useCreateActivityStatusRenderer.tsx +65 -34
- package/src/hooks/useCreateAvatarRenderer.ts +24 -20
- package/src/hooks/useDateFormatter.ts +4 -3
- package/src/hooks/useGetActivityByKey.ts +3 -0
- package/src/hooks/useGetHasAcknowledgedByActivityKey.ts +3 -0
- package/src/hooks/useGetKeyByActivity.ts +3 -0
- package/src/hooks/useGetKeyByActivityId.ts +3 -0
- package/src/hooks/useGetSendTimeoutForActivity.ts +9 -8
- package/src/hooks/useGroupActivities.ts +4 -8
- package/src/hooks/useLastAcknowledgedActivityKey.ts +3 -0
- package/src/hooks/useLastReadActivityKey.ts +3 -0
- package/src/hooks/useLocalizer.ts +7 -2
- package/src/hooks/useMarkActivityAsSpoken.ts +2 -2
- package/src/hooks/useMarkActivityKeyAsRead.ts +3 -0
- package/src/hooks/useMarkAllAsAcknowledged.ts +3 -0
- package/src/hooks/usePerformCardAction.ts +2 -3
- package/src/hooks/usePostActivity.ts +2 -2
- package/src/hooks/useSendFiles.ts +8 -1
- package/src/hooks/useSendTimeoutForActivity.ts +2 -2
- package/src/hooks/useSubmitSendBox.ts +2 -5
- package/src/hooks/useSuggestedActions.ts +1 -1
- package/src/hooks/useTimeoutForSend.ts +2 -2
- package/src/localization/Localize.ts +9 -2
- package/src/localization/ar-SA.json +23 -4
- package/src/localization/bg-BG.json +23 -4
- package/src/localization/ca-ES.json +23 -4
- package/src/localization/cs-CZ.json +23 -4
- package/src/localization/da-DK.json +23 -4
- package/src/localization/de-DE.json +23 -4
- package/src/localization/el-GR.json +23 -4
- package/src/localization/en-US.json +34 -9
- package/src/localization/es-ES.json +23 -4
- package/src/localization/et-EE.json +23 -4
- package/src/localization/eu-ES.json +23 -4
- package/src/localization/fi-FI.json +23 -4
- package/src/localization/fr-FR.json +23 -4
- package/src/localization/gl-ES.json +23 -4
- package/src/localization/he-IL.json +23 -4
- package/src/localization/hi-IN.json +23 -4
- package/src/localization/hr-HR.json +23 -4
- package/src/localization/hu-HU.json +23 -4
- package/src/localization/id-ID.json +23 -4
- package/src/localization/it-IT.json +23 -4
- package/src/localization/ja-JP.json +23 -4
- package/src/localization/kk-KZ.json +23 -4
- package/src/localization/ko-KR.json +23 -4
- package/src/localization/lt-LT.json +23 -4
- package/src/localization/lv-LV.json +23 -4
- package/src/localization/mergeLocalizedStrings.ts +7 -1
- package/src/localization/ms-MY.json +23 -4
- package/src/localization/nb-NO.json +23 -4
- package/src/localization/nl-NL.json +23 -4
- package/src/localization/pl-PL.json +23 -4
- package/src/localization/pt-BR.json +23 -4
- package/src/localization/pt-PT.json +23 -4
- package/src/localization/ro-RO.json +23 -4
- package/src/localization/ru-RU.json +23 -4
- package/src/localization/sk-SK.json +23 -4
- package/src/localization/sl-SI.json +23 -4
- package/src/localization/sr-Cyrl-CS.json +23 -4
- package/src/localization/sr-Latn-CS.json +23 -4
- package/src/localization/sv-SE.json +23 -4
- package/src/localization/th-TH.json +23 -4
- package/src/localization/tr-TR.json +23 -4
- package/src/localization/uk-UA.json +23 -4
- package/src/localization/vi-VN.json +23 -4
- package/src/localization/yue.json +26 -7
- package/src/localization/zh-CN.json +23 -4
- package/src/localization/zh-HK.json +23 -4
- package/src/localization/zh-TW.json +23 -4
- package/src/normalizeStyleOptions.ts +70 -0
- package/src/patchStyleOptionsFromDeprecatedProps.js +0 -2
- package/src/providers/ActivityAcknowledgement/ActivityAcknowledgementComposer.tsx +180 -0
- package/src/providers/ActivityAcknowledgement/private/Context.ts +18 -0
- package/src/providers/ActivityAcknowledgement/private/types.ts +6 -0
- package/src/providers/ActivityAcknowledgement/private/useContext.ts +19 -0
- package/src/providers/ActivityAcknowledgement/useActivityKeysByRead.tsx +8 -0
- package/src/providers/ActivityAcknowledgement/useGetHasAcknowledgedByActivityKey.ts +5 -0
- package/src/providers/ActivityAcknowledgement/useLastAcknowledgedActivityKey.ts +5 -0
- package/src/providers/ActivityAcknowledgement/useLastReadActivityKey.ts +5 -0
- package/src/providers/ActivityAcknowledgement/useMarkActivityKeyAsRead.ts +5 -0
- package/src/providers/ActivityAcknowledgement/useMarkAllAsAcknowledged.ts +5 -0
- package/src/providers/ActivityKeyer/ActivityKeyerComposer.tsx +150 -0
- package/src/providers/ActivityKeyer/private/Context.ts +13 -0
- package/src/providers/ActivityKeyer/private/getActivityId.ts +5 -0
- package/src/providers/ActivityKeyer/private/getClientActivityId.ts +5 -0
- package/src/providers/ActivityKeyer/private/uniqueId.ts +8 -0
- package/src/providers/ActivityKeyer/private/useContext.ts +15 -0
- package/src/providers/ActivityKeyer/useActivityKeys.ts +5 -0
- package/src/providers/ActivityKeyer/useGetActivityByKey.ts +7 -0
- package/src/providers/ActivityKeyer/useGetKeyByActivity.ts +7 -0
- package/src/providers/ActivityKeyer/useGetKeyByActivityId.ts +5 -0
- package/src/types/ActivityMiddleware.ts +3 -3
- package/src/types/ActivityStatusMiddleware.ts +3 -3
- package/src/types/AttachmentForScreenReaderMiddleware.ts +2 -2
- package/src/types/AttachmentMiddleware.ts +2 -2
- package/src/types/AvatarMiddleware.ts +2 -2
- package/src/types/CardActionMiddleware.ts +2 -2
- package/src/types/GroupActivitiesMiddleware.ts +7 -7
- package/src/utils/createCustomEvent.ts +7 -1
- package/src/utils/findLastIndex.spec.js +31 -0
- package/src/utils/findLastIndex.ts +11 -0
- package/src/utils/mapMap.ts +7 -1
- package/src/utils/randomId.ts +1 -1
- package/.eslintignore +0 -1
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import React, { useCallback, useMemo, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { FC, PropsWithChildren } from 'react';
|
|
4
|
+
|
|
5
|
+
import ActivityAcknowledgementContext, { ActivityAcknowledgementContextType } from './private/Context';
|
|
6
|
+
import findLastIndex from '../../utils/findLastIndex';
|
|
7
|
+
import useActivities from '../../hooks/useActivities';
|
|
8
|
+
import useActivityKeys from '../ActivityKeyer/useActivityKeys';
|
|
9
|
+
import usePrevious from '../../hooks/internal/usePrevious';
|
|
10
|
+
import useValueRef from '../../hooks/internal/useValueRef';
|
|
11
|
+
|
|
12
|
+
import type { ActivityAcknowledgement } from './private/types';
|
|
13
|
+
|
|
14
|
+
type ActivityAcknowledgementComposerProps = PropsWithChildren<{}>;
|
|
15
|
+
|
|
16
|
+
function findClosestActivityKeyIfNotExists(
|
|
17
|
+
activityKey: string,
|
|
18
|
+
keys: readonly string[],
|
|
19
|
+
prevKeys: readonly string[]
|
|
20
|
+
): string | undefined {
|
|
21
|
+
if (keys.includes(activityKey)) {
|
|
22
|
+
return activityKey;
|
|
23
|
+
} else if (!prevKeys || !activityKey) {
|
|
24
|
+
// Initially, when the transcript was empty, there should be nothing read.
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// If the last activity key is no longer in this activities (say, deleted), we try to find the closest one.
|
|
29
|
+
const prevIndex = prevKeys.indexOf(activityKey);
|
|
30
|
+
|
|
31
|
+
if (~prevIndex) {
|
|
32
|
+
// List out all previously activity keys, find the closest one that is in the new transcript.
|
|
33
|
+
const acknowledgedActivityKeys = prevKeys.slice(0, prevIndex).reverse();
|
|
34
|
+
|
|
35
|
+
for (const prevAcknowledgedActivityKey of acknowledgedActivityKeys) {
|
|
36
|
+
if (keys.includes(prevAcknowledgedActivityKey)) {
|
|
37
|
+
return prevAcknowledgedActivityKey;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// If nothing is found, return `undefined`.
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const ActivityAcknowledgementComposer: FC<ActivityAcknowledgementComposerProps> = ({ children }) => {
|
|
46
|
+
const [activities] = useActivities();
|
|
47
|
+
const [allActivityKeys] = useActivityKeys();
|
|
48
|
+
const [rawLastAcknowledgedActivityKey, setRawLastAcknowledgedActivityKey] = useState<string | undefined>();
|
|
49
|
+
const [rawLastReadActivityKey, setRawLastReadActivityKey] = useState<string | undefined>();
|
|
50
|
+
|
|
51
|
+
const allActivityKeysRef = useValueRef(allActivityKeys);
|
|
52
|
+
const prevAllActivityKeys = usePrevious(allActivityKeys);
|
|
53
|
+
|
|
54
|
+
const lastOutgoingActivityKeyIndex = useMemo(
|
|
55
|
+
() => findLastIndex(activities, activity => activity.from?.role === 'user'),
|
|
56
|
+
[activities]
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
// Make sure when we return "lastReadActivityKey" exists in the current transcript.
|
|
60
|
+
const lastReadActivityKey = useMemo(() => {
|
|
61
|
+
rawLastReadActivityKey &&
|
|
62
|
+
!~prevAllActivityKeys.includes(rawLastReadActivityKey) &&
|
|
63
|
+
console.warn(
|
|
64
|
+
`botframework-webchat internal assertion: "rawLastReadActivityKey" of value ${rawLastReadActivityKey} should be in the "prevAllActivityKeys" array.`
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
return findClosestActivityKeyIfNotExists(rawLastReadActivityKey, allActivityKeys, prevAllActivityKeys);
|
|
68
|
+
}, [allActivityKeys, prevAllActivityKeys, rawLastReadActivityKey]);
|
|
69
|
+
|
|
70
|
+
const lastReadActivityKeyRef = useValueRef(lastReadActivityKey);
|
|
71
|
+
|
|
72
|
+
// Make sure when we return "lastAcknowledgedActivityKey" exists in the current transcript.
|
|
73
|
+
const lastAcknowledgedActivityKey = useMemo(() => {
|
|
74
|
+
rawLastAcknowledgedActivityKey &&
|
|
75
|
+
!~prevAllActivityKeys.includes(rawLastAcknowledgedActivityKey) &&
|
|
76
|
+
console.warn(
|
|
77
|
+
`botframework-webchat internal assertion: "rawLastAcknowledgedActivityKey" of value ${rawLastAcknowledgedActivityKey} should be in the "prevAllActivityKeys" array.`
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
const lastAcknowledgedActivityKey = findClosestActivityKeyIfNotExists(
|
|
81
|
+
rawLastAcknowledgedActivityKey,
|
|
82
|
+
allActivityKeys,
|
|
83
|
+
prevAllActivityKeys
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// TODO: [P2] Since Direct Line may send history and does not have read receipt.
|
|
87
|
+
// Thus, if we don't assume everything is acknowledged initially, while displaying the history,
|
|
88
|
+
// the transcript would soon stop scrolling.
|
|
89
|
+
// Thus, before the first outgoing activity is detected, we need to assume everything is acknowledged.
|
|
90
|
+
return (
|
|
91
|
+
allActivityKeys[Math.max(allActivityKeys.indexOf(lastAcknowledgedActivityKey), lastOutgoingActivityKeyIndex)] ||
|
|
92
|
+
allActivityKeys[allActivityKeys.length - 1]
|
|
93
|
+
);
|
|
94
|
+
}, [allActivityKeys, lastOutgoingActivityKeyIndex, prevAllActivityKeys, rawLastAcknowledgedActivityKey]);
|
|
95
|
+
|
|
96
|
+
const activityAcknowledgements = useMemo<Readonly<Map<string, ActivityAcknowledgement>>>(() => {
|
|
97
|
+
const activityAcknowledgements = new Map<string, ActivityAcknowledgement>();
|
|
98
|
+
const lastAcknowledgedIndex = allActivityKeys.indexOf(lastAcknowledgedActivityKey);
|
|
99
|
+
const lastReadIndex = allActivityKeys.indexOf(lastReadActivityKey);
|
|
100
|
+
|
|
101
|
+
allActivityKeys.forEach((activityKey, index) => {
|
|
102
|
+
activityAcknowledgements.set(activityKey, {
|
|
103
|
+
acknowledged: index <= lastAcknowledgedIndex,
|
|
104
|
+
read: index <= lastReadIndex
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
return Object.freeze(activityAcknowledgements);
|
|
109
|
+
}, [allActivityKeys, lastAcknowledgedActivityKey, lastReadActivityKey]);
|
|
110
|
+
|
|
111
|
+
const activityAcknowledgementsRef = useValueRef(activityAcknowledgements);
|
|
112
|
+
|
|
113
|
+
const getHasAcknowledgedByActivityKey = useCallback<(activityKey: string) => boolean>(
|
|
114
|
+
(activityKey: string) => activityAcknowledgementsRef.current.get(activityKey)?.acknowledged,
|
|
115
|
+
[activityAcknowledgementsRef]
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
// TODO: [P2] Memoize with `useMemoWithPrevious` for better memoization of arrays.
|
|
119
|
+
const activityKeysByReadState = useMemo<readonly [readonly string[], readonly string[]]>(() => {
|
|
120
|
+
const index = allActivityKeys.indexOf(lastReadActivityKey);
|
|
121
|
+
|
|
122
|
+
return Object.freeze([
|
|
123
|
+
Object.freeze(allActivityKeys.slice(0, index + 1)),
|
|
124
|
+
Object.freeze(allActivityKeys.slice(index + 1))
|
|
125
|
+
]) as readonly [readonly string[], readonly string[]];
|
|
126
|
+
}, [allActivityKeys, lastReadActivityKey]);
|
|
127
|
+
|
|
128
|
+
const markAllAsAcknowledged = useCallback((): void => {
|
|
129
|
+
const { current: allActivityKeys } = allActivityKeysRef;
|
|
130
|
+
|
|
131
|
+
setRawLastAcknowledgedActivityKey(allActivityKeys[allActivityKeys.length - 1]);
|
|
132
|
+
}, [allActivityKeysRef, setRawLastAcknowledgedActivityKey]);
|
|
133
|
+
|
|
134
|
+
const markActivityKeyAsRead = useCallback(
|
|
135
|
+
(activityKey: string): void => {
|
|
136
|
+
const { current: allActivityKeys } = allActivityKeysRef;
|
|
137
|
+
const index = allActivityKeys.indexOf(activityKey);
|
|
138
|
+
|
|
139
|
+
if (!~index) {
|
|
140
|
+
return console.warn(
|
|
141
|
+
`botframework-webchat: Cannot mark activity with key ${activityKey} as read because it is not in the transcript.`
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
index > allActivityKeys.indexOf(lastReadActivityKeyRef.current) && setRawLastReadActivityKey(activityKey);
|
|
146
|
+
},
|
|
147
|
+
[allActivityKeysRef, lastReadActivityKeyRef, setRawLastReadActivityKey]
|
|
148
|
+
);
|
|
149
|
+
|
|
150
|
+
if (activityKeysByReadState[0].length + activityKeysByReadState[1].length !== allActivityKeys.length) {
|
|
151
|
+
console.warn(
|
|
152
|
+
'botframework-webchat internal: Sum of count of read and unread activity keys MUST equals to total number of activity keys.'
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const contextValue = useMemo<ActivityAcknowledgementContextType>(
|
|
157
|
+
() => ({
|
|
158
|
+
activityKeysByReadState,
|
|
159
|
+
getHasAcknowledgedByActivityKey,
|
|
160
|
+
lastAcknowledgedActivityKeyState: Object.freeze([lastAcknowledgedActivityKey]) as readonly [string],
|
|
161
|
+
lastReadActivityKeyState: Object.freeze([lastReadActivityKey]) as readonly [string],
|
|
162
|
+
markActivityKeyAsRead,
|
|
163
|
+
markAllAsAcknowledged
|
|
164
|
+
}),
|
|
165
|
+
[
|
|
166
|
+
activityKeysByReadState,
|
|
167
|
+
getHasAcknowledgedByActivityKey,
|
|
168
|
+
lastAcknowledgedActivityKey,
|
|
169
|
+
lastReadActivityKey,
|
|
170
|
+
markActivityKeyAsRead,
|
|
171
|
+
markAllAsAcknowledged
|
|
172
|
+
]
|
|
173
|
+
);
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<ActivityAcknowledgementContext.Provider value={contextValue}>{children}</ActivityAcknowledgementContext.Provider>
|
|
177
|
+
);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
export default ActivityAcknowledgementComposer;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
|
|
3
|
+
// TODO: [P1] It seems acknowledgement is only for transcript scrolling and not very beneficial to everyone.
|
|
4
|
+
// We should move acknowledgement logic to transcript.
|
|
5
|
+
type ActivityAcknowledgementContextType = {
|
|
6
|
+
activityKeysByReadState: readonly [readonly string[], readonly string[]];
|
|
7
|
+
getHasAcknowledgedByActivityKey: (activityKey: string) => boolean | undefined;
|
|
8
|
+
lastAcknowledgedActivityKeyState: readonly [string];
|
|
9
|
+
lastReadActivityKeyState: readonly [string];
|
|
10
|
+
markActivityKeyAsRead: (activityKey: string) => void;
|
|
11
|
+
markAllAsAcknowledged: () => void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const ActivityAcknowledgementContext = createContext<ActivityAcknowledgementContextType>(undefined);
|
|
15
|
+
|
|
16
|
+
export default ActivityAcknowledgementContext;
|
|
17
|
+
|
|
18
|
+
export type { ActivityAcknowledgementContextType };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import ActivityAcknowledgementContext from './Context';
|
|
4
|
+
|
|
5
|
+
import type { ActivityAcknowledgementContextType } from './Context';
|
|
6
|
+
|
|
7
|
+
export default function useActivityAcknowledgementContext(
|
|
8
|
+
thrownOnUndefined = true
|
|
9
|
+
): ActivityAcknowledgementContextType {
|
|
10
|
+
const contextValue = useContext(ActivityAcknowledgementContext);
|
|
11
|
+
|
|
12
|
+
if (thrownOnUndefined && !contextValue) {
|
|
13
|
+
throw new Error(
|
|
14
|
+
'botframework-webchat internal: This hook can only be used under <ActivityAcknowledgementContext>.'
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return contextValue;
|
|
19
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import useActivityAcknowledgementContext from './private/useContext';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns an arrays of two list of activity keys: read and unread.
|
|
5
|
+
*/
|
|
6
|
+
export default function useActivityKeysByRead(): readonly [readonly string[], readonly string[]] {
|
|
7
|
+
return useActivityAcknowledgementContext().activityKeysByReadState;
|
|
8
|
+
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import PropTypes from 'prop-types';
|
|
2
|
+
import React, { useCallback, useMemo, useRef } from 'react';
|
|
3
|
+
import type { FC } from 'react';
|
|
4
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
5
|
+
|
|
6
|
+
import ActivityKeyerContext, { ActivityKeyerContextType } from './private/Context';
|
|
7
|
+
import getActivityId from './private/getActivityId';
|
|
8
|
+
import getClientActivityId from './private/getClientActivityId';
|
|
9
|
+
import uniqueId from './private/uniqueId';
|
|
10
|
+
import useActivities from '../../hooks/useActivities';
|
|
11
|
+
import useActivityKeyerContext from './private/useContext';
|
|
12
|
+
|
|
13
|
+
type ActivityIdToKeyMap = Map<string, string>;
|
|
14
|
+
type ActivityToKeyMap = Map<WebChatActivity, string>;
|
|
15
|
+
type ClientActivityIdToKeyMap = Map<string, string>;
|
|
16
|
+
type KeyToActivityMap = Map<string, WebChatActivity>;
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* React context composer component to assign a perma-key to every activity.
|
|
20
|
+
* This will support both `useGetActivityByKey` and `useGetKeyByActivity` custom hooks.
|
|
21
|
+
*
|
|
22
|
+
* Today, `activity.id` is only guaranteed for activity from others.
|
|
23
|
+
* Not all activities sent by the local user has `activity.id`.
|
|
24
|
+
*
|
|
25
|
+
* To track outgoing activities, we added `activity.channelData.clientActivityId`.
|
|
26
|
+
*
|
|
27
|
+
* This component will create a local key, which can be used to track both
|
|
28
|
+
* incoming and outgoing activities in a consistent way.
|
|
29
|
+
*
|
|
30
|
+
* Local key are only persisted in memory. On refresh, they will be a new random key.
|
|
31
|
+
*/
|
|
32
|
+
const ActivityKeyerComposer: FC<{}> = ({ children }) => {
|
|
33
|
+
const existingContext = useActivityKeyerContext(false);
|
|
34
|
+
|
|
35
|
+
if (existingContext) {
|
|
36
|
+
throw new Error('botframework-webchat internal: <ActivityKeyerComposer> should not be nested.');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const [activities] = useActivities();
|
|
40
|
+
const activityIdToKeyMapRef = useRef<Readonly<ActivityIdToKeyMap>>(Object.freeze(new Map()));
|
|
41
|
+
const activityToKeyMapRef = useRef<Readonly<ActivityToKeyMap>>(Object.freeze(new Map()));
|
|
42
|
+
const clientActivityIdToKeyMapRef = useRef<Readonly<ClientActivityIdToKeyMap>>(Object.freeze(new Map()));
|
|
43
|
+
const keyToActivityMapRef = useRef<Readonly<KeyToActivityMap>>(Object.freeze(new Map()));
|
|
44
|
+
|
|
45
|
+
// TODO: [P1] `useMemoWithPrevious` to check and cache the resulting array if it hasn't changed.
|
|
46
|
+
const activityKeysState = useMemo<readonly [readonly string[]]>(() => {
|
|
47
|
+
const { current: activityIdToKeyMap } = activityIdToKeyMapRef;
|
|
48
|
+
const { current: activityToKeyMap } = activityToKeyMapRef;
|
|
49
|
+
const { current: clientActivityIdToKeyMap } = clientActivityIdToKeyMapRef;
|
|
50
|
+
const nextActivityIdToKeyMap: ActivityIdToKeyMap = new Map();
|
|
51
|
+
const nextActivityKeys: string[] = [];
|
|
52
|
+
const nextActivityToKeyMap: ActivityToKeyMap = new Map();
|
|
53
|
+
const nextClientActivityIdToKeyMap: ClientActivityIdToKeyMap = new Map();
|
|
54
|
+
const nextKeyToActivityMap: KeyToActivityMap = new Map();
|
|
55
|
+
|
|
56
|
+
activities.forEach(activity => {
|
|
57
|
+
const activityId = getActivityId(activity);
|
|
58
|
+
const clientActivityId = getClientActivityId(activity);
|
|
59
|
+
|
|
60
|
+
const key =
|
|
61
|
+
(clientActivityId && clientActivityIdToKeyMap.get(clientActivityId)) ||
|
|
62
|
+
(activityId && activityIdToKeyMap.get(activityId)) ||
|
|
63
|
+
activityToKeyMap.get(activity) ||
|
|
64
|
+
uniqueId();
|
|
65
|
+
|
|
66
|
+
activityId && nextActivityIdToKeyMap.set(activityId, key);
|
|
67
|
+
clientActivityId && nextClientActivityIdToKeyMap.set(clientActivityId, key);
|
|
68
|
+
nextActivityToKeyMap.set(activity, key);
|
|
69
|
+
nextKeyToActivityMap.set(key, activity);
|
|
70
|
+
nextActivityKeys.push(key);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
activityIdToKeyMapRef.current = Object.freeze(nextActivityIdToKeyMap);
|
|
74
|
+
activityToKeyMapRef.current = Object.freeze(nextActivityToKeyMap);
|
|
75
|
+
clientActivityIdToKeyMapRef.current = Object.freeze(nextClientActivityIdToKeyMap);
|
|
76
|
+
keyToActivityMapRef.current = Object.freeze(nextKeyToActivityMap);
|
|
77
|
+
|
|
78
|
+
// `nextActivityKeys` could potentially same as `prevActivityKeys` despite reference differences, we should memoize it.
|
|
79
|
+
return Object.freeze([Object.freeze(nextActivityKeys)]) as readonly [readonly string[]];
|
|
80
|
+
}, [activities, activityIdToKeyMapRef, activityToKeyMapRef, clientActivityIdToKeyMapRef, keyToActivityMapRef]);
|
|
81
|
+
|
|
82
|
+
const getActivityByKey: (key?: string) => undefined | WebChatActivity = useCallback(
|
|
83
|
+
(key?: string): undefined | WebChatActivity => key && keyToActivityMapRef.current.get(key),
|
|
84
|
+
[keyToActivityMapRef]
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const getKeyByActivity: (activity?: WebChatActivity) => string | undefined = useCallback(
|
|
88
|
+
(activity?: WebChatActivity) => activity && activityToKeyMapRef.current.get(activity),
|
|
89
|
+
[activityToKeyMapRef]
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
const getKeyByActivityId: (activityId?: string) => string | undefined = useCallback(
|
|
93
|
+
(activityId?: string) => activityId && activityIdToKeyMapRef.current.get(activityId),
|
|
94
|
+
[activityIdToKeyMapRef]
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const contextValue = useMemo<ActivityKeyerContextType>(
|
|
98
|
+
() => ({
|
|
99
|
+
activityKeysState,
|
|
100
|
+
getActivityByKey,
|
|
101
|
+
getKeyByActivity,
|
|
102
|
+
getKeyByActivityId
|
|
103
|
+
}),
|
|
104
|
+
[activityKeysState, getActivityByKey, getKeyByActivity, getKeyByActivityId]
|
|
105
|
+
);
|
|
106
|
+
|
|
107
|
+
const { length: numActivities } = activities;
|
|
108
|
+
|
|
109
|
+
if (activityIdToKeyMapRef.current.size > numActivities) {
|
|
110
|
+
console.warn(
|
|
111
|
+
'botframework-webchat internal assertion: "activityIdToKeyMap.size" should be equal or less than "activities.length".'
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (activityToKeyMapRef.current.size !== numActivities) {
|
|
116
|
+
console.warn(
|
|
117
|
+
'botframework-webchat internal assertion: "activityToKeyMap.size" should be same as "activities.length".'
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (clientActivityIdToKeyMapRef.current.size > numActivities) {
|
|
122
|
+
console.warn(
|
|
123
|
+
'botframework-webchat internal assertion: "clientActivityIdToKeyMap.size" should be equal or less than "activities.length".'
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (keyToActivityMapRef.current.size !== numActivities) {
|
|
128
|
+
console.warn(
|
|
129
|
+
'botframework-webchat internal assertion: "keyToActivityMap.size" should be same as "activities.length".'
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (activityKeysState[0].length !== numActivities) {
|
|
134
|
+
console.warn(
|
|
135
|
+
'botframework-webchat internal assertion: "activityKeys.length" should be same as "activities.length".'
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return <ActivityKeyerContext.Provider value={contextValue}>{children}</ActivityKeyerContext.Provider>;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
ActivityKeyerComposer.defaultProps = {
|
|
143
|
+
children: undefined
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
ActivityKeyerComposer.propTypes = {
|
|
147
|
+
children: PropTypes.any
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export default ActivityKeyerComposer;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { createContext } from 'react';
|
|
2
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
3
|
+
|
|
4
|
+
type ActivityKeyerContextType = {
|
|
5
|
+
activityKeysState: readonly [readonly string[]];
|
|
6
|
+
getActivityByKey: (key?: string) => undefined | WebChatActivity;
|
|
7
|
+
getKeyByActivity: (activity?: WebChatActivity) => string | undefined;
|
|
8
|
+
getKeyByActivityId: (activityKey?: string) => string | undefined;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export default createContext<ActivityKeyerContextType>(undefined);
|
|
12
|
+
|
|
13
|
+
export type { ActivityKeyerContextType };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import random from 'math-random';
|
|
2
|
+
|
|
3
|
+
// This format ID must be compatible with HTML "className" and "id" attribute.
|
|
4
|
+
// It will be suffixed as "webchat__activity--{id}".
|
|
5
|
+
export default function uniqueId(): string {
|
|
6
|
+
// eslint-disable-next-line no-magic-numbers
|
|
7
|
+
return random().toString(36).substring(2, 7);
|
|
8
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
import ActivityKeyerContext from './Context';
|
|
4
|
+
|
|
5
|
+
import type { ActivityKeyerContextType } from './Context';
|
|
6
|
+
|
|
7
|
+
export default function useActivityKeyerContext(thrownOnUndefined = true): ActivityKeyerContextType {
|
|
8
|
+
const contextValue = useContext(ActivityKeyerContext);
|
|
9
|
+
|
|
10
|
+
if (thrownOnUndefined && !contextValue) {
|
|
11
|
+
throw new Error('botframework-webchat internal: This hook can only be used under <ActivityKeyerComposer>.');
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return contextValue;
|
|
15
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
2
|
+
|
|
3
|
+
import useActivityKeyerContext from './private/useContext';
|
|
4
|
+
|
|
5
|
+
export default function useGetActivityByKey(): (key?: string) => undefined | WebChatActivity {
|
|
6
|
+
return useActivityKeyerContext().getActivityByKey;
|
|
7
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
2
|
+
|
|
3
|
+
import useActivityKeyerContext from './private/useContext';
|
|
4
|
+
|
|
5
|
+
export default function useGetKeyByActivity(): (activity?: WebChatActivity) => string | undefined {
|
|
6
|
+
return useActivityKeyerContext().getKeyByActivity;
|
|
7
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { DirectLineActivity } from 'botframework-webchat-core';
|
|
2
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
3
3
|
|
|
4
4
|
import { AvatarComponentFactory } from './AvatarMiddleware';
|
|
5
5
|
import { RenderAttachment } from './AttachmentMiddleware';
|
|
@@ -14,8 +14,8 @@ type ActivityProps = {
|
|
|
14
14
|
type ActivityComponent = (props: ActivityProps) => Exclude<ReactNode, boolean>;
|
|
15
15
|
|
|
16
16
|
type ActivityComponentFactoryOptions = {
|
|
17
|
-
activity:
|
|
18
|
-
nextVisibleActivity:
|
|
17
|
+
activity: WebChatActivity;
|
|
18
|
+
nextVisibleActivity: WebChatActivity;
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
type ActivityComponentFactory = (options: ActivityComponentFactoryOptions) => ActivityComponent | false;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
import { DirectLineActivity } from 'botframework-webchat-core';
|
|
2
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
3
3
|
|
|
4
4
|
import SendState from './SendState';
|
|
5
5
|
|
|
6
6
|
// TODO: Migrate this legacy middleware signature.
|
|
7
7
|
type RenderActivityStatusOptions = {
|
|
8
|
-
activity:
|
|
8
|
+
activity: WebChatActivity;
|
|
9
9
|
hideTimestamp: boolean;
|
|
10
10
|
sendState: SendState;
|
|
11
11
|
|
|
12
12
|
// "nextVisibleActivity" is for backward compatibility, please remove this line on or after 2022-07-22.
|
|
13
13
|
/** @deprecated */
|
|
14
|
-
nextVisibleActivity:
|
|
14
|
+
nextVisibleActivity: WebChatActivity;
|
|
15
15
|
|
|
16
16
|
// "sameTimestampGroup" is for backward compatibility, please remove this line on or after 2022-07-22.
|
|
17
17
|
/** @deprecated */
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { DirectLineAttachment, WebChatActivity } from 'botframework-webchat-core';
|
|
2
2
|
|
|
3
3
|
// TODO: We should consider using a prop for "attachmentMiddleware" to render for screen reader, instead of having another middleware.
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@ import ComponentMiddleware, { ComponentFactory } from './ComponentMiddleware';
|
|
|
6
6
|
|
|
7
7
|
type AttachmentForScreenReaderComponentFactoryOptions = [
|
|
8
8
|
{
|
|
9
|
-
activity:
|
|
9
|
+
activity: WebChatActivity;
|
|
10
10
|
attachment: DirectLineAttachment;
|
|
11
11
|
}
|
|
12
12
|
];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DirectLineActivity, DirectLineAttachment } from 'botframework-webchat-core';
|
|
2
1
|
import { ReactNode } from 'react';
|
|
2
|
+
import type { DirectLineAttachment, WebChatActivity } from 'botframework-webchat-core';
|
|
3
3
|
|
|
4
4
|
type AttachmentProps = {
|
|
5
|
-
activity:
|
|
5
|
+
activity: WebChatActivity;
|
|
6
6
|
attachment: DirectLineAttachment;
|
|
7
7
|
};
|
|
8
8
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
2
2
|
|
|
3
3
|
import { StrictStyleOptions } from '../StyleOptions';
|
|
4
4
|
import ComponentMiddleware, { ComponentFactory } from './ComponentMiddleware';
|
|
5
5
|
|
|
6
6
|
type AvatarComponentFactoryArguments = [
|
|
7
7
|
{
|
|
8
|
-
activity:
|
|
8
|
+
activity: WebChatActivity;
|
|
9
9
|
fromUser: boolean;
|
|
10
10
|
styleOptions: StrictStyleOptions;
|
|
11
11
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { DirectLineCardAction } from 'botframework-webchat-core';
|
|
1
|
+
import type { DirectLineCardAction } from 'botframework-webchat-core';
|
|
2
2
|
|
|
3
3
|
import FunctionMiddleware from './FunctionMiddleware';
|
|
4
4
|
|
|
5
|
-
type PerformCardAction = (cardAction: DirectLineCardAction) => void;
|
|
5
|
+
type PerformCardAction = (cardAction: DirectLineCardAction, { target: EventTarget }?) => void;
|
|
6
6
|
|
|
7
7
|
type CardActionMiddleware = FunctionMiddleware<
|
|
8
8
|
[{ dispatch: (action: any) => void }],
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { WebChatActivity } from 'botframework-webchat-core';
|
|
2
2
|
|
|
3
3
|
import FunctionMiddleware, { CallFunction } from './FunctionMiddleware';
|
|
4
4
|
|
|
5
5
|
type GroupActivities = CallFunction<
|
|
6
|
-
[{ activities:
|
|
6
|
+
[{ activities: WebChatActivity[] }],
|
|
7
7
|
{
|
|
8
|
-
sender:
|
|
9
|
-
status:
|
|
8
|
+
sender: WebChatActivity[][];
|
|
9
|
+
status: WebChatActivity[][];
|
|
10
10
|
}
|
|
11
11
|
>;
|
|
12
12
|
|
|
13
13
|
type GroupActivitiesMiddleware = FunctionMiddleware<
|
|
14
14
|
[],
|
|
15
|
-
[{ activities:
|
|
15
|
+
[{ activities: WebChatActivity[] }],
|
|
16
16
|
{
|
|
17
|
-
sender:
|
|
18
|
-
status:
|
|
17
|
+
sender: WebChatActivity[][];
|
|
18
|
+
status: WebChatActivity[][];
|
|
19
19
|
}
|
|
20
20
|
>;
|
|
21
21
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { isForbiddenPropertyName } from 'botframework-webchat-core';
|
|
2
|
+
|
|
1
3
|
export default function createCustomEvent<T>(
|
|
2
4
|
name: string,
|
|
3
5
|
eventInitDict: T
|
|
@@ -15,7 +17,11 @@ export default function createCustomEvent<T>(
|
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
Object.entries(eventInitDict).forEach(([key, value]) => {
|
|
18
|
-
|
|
20
|
+
if (!isForbiddenPropertyName(key)) {
|
|
21
|
+
// Mitigation through denylisting.
|
|
22
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
23
|
+
event[key] = value;
|
|
24
|
+
}
|
|
19
25
|
});
|
|
20
26
|
|
|
21
27
|
return event as any;
|