botframework-webchat-api 4.15.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.
Files changed (121) hide show
  1. package/lib/StyleOptions.d.ts +2 -2
  2. package/lib/StyleOptions.d.ts.map +1 -1
  3. package/lib/hooks/Composer.d.ts +2 -2
  4. package/lib/hooks/Composer.d.ts.map +1 -1
  5. package/lib/hooks/Composer.js +6 -4
  6. package/lib/hooks/internal/WebChatAPIContext.d.ts +3 -3
  7. package/lib/hooks/internal/WebChatAPIContext.d.ts.map +1 -1
  8. package/lib/hooks/internal/WebChatAPIContext.js +1 -1
  9. package/lib/hooks/internal/useReadTelemetryDimensions.js +2 -2
  10. package/lib/hooks/middleware/UserlandBoundary.js +1 -1
  11. package/lib/hooks/middleware/applyMiddleware.js +1 -1
  12. package/lib/hooks/middleware/createDefaultGroupActivitiesMiddleware.d.ts.map +1 -1
  13. package/lib/hooks/middleware/createDefaultGroupActivitiesMiddleware.js +19 -3
  14. package/lib/hooks/useActiveTyping.d.ts.map +1 -1
  15. package/lib/hooks/useActiveTyping.js +5 -4
  16. package/lib/hooks/useActivities.d.ts +2 -2
  17. package/lib/hooks/useActivities.d.ts.map +1 -1
  18. package/lib/hooks/useActivities.js +1 -1
  19. package/lib/hooks/useCreateActivityStatusRenderer.d.ts +3 -3
  20. package/lib/hooks/useCreateActivityStatusRenderer.d.ts.map +1 -1
  21. package/lib/hooks/useCreateActivityStatusRenderer.js +47 -16
  22. package/lib/hooks/useCreateAvatarRenderer.d.ts +2 -2
  23. package/lib/hooks/useCreateAvatarRenderer.d.ts.map +1 -1
  24. package/lib/hooks/useCreateAvatarRenderer.js +1 -1
  25. package/lib/hooks/useDebouncedNotifications.js +2 -2
  26. package/lib/hooks/useGetSendTimeoutForActivity.d.ts +2 -2
  27. package/lib/hooks/useGetSendTimeoutForActivity.d.ts.map +1 -1
  28. package/lib/hooks/useGetSendTimeoutForActivity.js +4 -2
  29. package/lib/hooks/useGroupActivities.d.ts +4 -4
  30. package/lib/hooks/useGroupActivities.d.ts.map +1 -1
  31. package/lib/hooks/useGroupActivities.js +1 -1
  32. package/lib/hooks/useLocalizer.js +1 -1
  33. package/lib/hooks/useMarkActivityAsSpoken.d.ts +2 -2
  34. package/lib/hooks/useMarkActivityAsSpoken.d.ts.map +1 -1
  35. package/lib/hooks/useMarkActivityAsSpoken.js +1 -1
  36. package/lib/hooks/usePostActivity.d.ts +2 -2
  37. package/lib/hooks/usePostActivity.d.ts.map +1 -1
  38. package/lib/hooks/usePostActivity.js +1 -1
  39. package/lib/hooks/useSendFiles.d.ts +8 -1
  40. package/lib/hooks/useSendFiles.d.ts.map +1 -1
  41. package/lib/hooks/useSendFiles.js +1 -1
  42. package/lib/hooks/useSendTimeoutForActivity.d.ts +2 -2
  43. package/lib/hooks/useSendTimeoutForActivity.d.ts.map +1 -1
  44. package/lib/hooks/useSendTimeoutForActivity.js +1 -1
  45. package/lib/hooks/useSuggestedActions.d.ts +1 -1
  46. package/lib/hooks/useSuggestedActions.d.ts.map +1 -1
  47. package/lib/hooks/useSuggestedActions.js +1 -1
  48. package/lib/hooks/useTimeoutForSend.d.ts +2 -2
  49. package/lib/hooks/useTimeoutForSend.d.ts.map +1 -1
  50. package/lib/hooks/useTimeoutForSend.js +1 -1
  51. package/lib/hooks/useTrackException.js +2 -2
  52. package/lib/hooks/utils/ErrorBoundary.js +3 -3
  53. package/lib/index.js +1 -1
  54. package/lib/localization/en-US.json +5 -2
  55. package/lib/localization/mergeLocalizedStrings.js +2 -2
  56. package/lib/normalizeStyleOptions.js +2 -2
  57. package/lib/providers/ActivityAcknowledgement/ActivityAcknowledgementComposer.js +1 -1
  58. package/lib/providers/ActivityKeyer/ActivityKeyerComposer.d.ts.map +1 -1
  59. package/lib/providers/ActivityKeyer/ActivityKeyerComposer.js +2 -2
  60. package/lib/providers/ActivityKeyer/private/Context.d.ts +3 -3
  61. package/lib/providers/ActivityKeyer/private/Context.d.ts.map +1 -1
  62. package/lib/providers/ActivityKeyer/private/Context.js +1 -1
  63. package/lib/providers/ActivityKeyer/private/getActivityId.d.ts +2 -2
  64. package/lib/providers/ActivityKeyer/private/getActivityId.d.ts.map +1 -1
  65. package/lib/providers/ActivityKeyer/private/getActivityId.js +1 -1
  66. package/lib/providers/ActivityKeyer/private/getClientActivityId.d.ts +2 -2
  67. package/lib/providers/ActivityKeyer/private/getClientActivityId.d.ts.map +1 -1
  68. package/lib/providers/ActivityKeyer/private/getClientActivityId.js +1 -1
  69. package/lib/providers/ActivityKeyer/useGetActivityByKey.d.ts +2 -2
  70. package/lib/providers/ActivityKeyer/useGetActivityByKey.d.ts.map +1 -1
  71. package/lib/providers/ActivityKeyer/useGetActivityByKey.js +1 -1
  72. package/lib/providers/ActivityKeyer/useGetKeyByActivity.d.ts +2 -2
  73. package/lib/providers/ActivityKeyer/useGetKeyByActivity.d.ts.map +1 -1
  74. package/lib/providers/ActivityKeyer/useGetKeyByActivity.js +1 -1
  75. package/lib/types/ActivityMiddleware.d.ts +3 -3
  76. package/lib/types/ActivityMiddleware.d.ts.map +1 -1
  77. package/lib/types/ActivityStatusMiddleware.d.ts +3 -3
  78. package/lib/types/ActivityStatusMiddleware.d.ts.map +1 -1
  79. package/lib/types/AttachmentForScreenReaderMiddleware.d.ts +2 -2
  80. package/lib/types/AttachmentForScreenReaderMiddleware.d.ts.map +1 -1
  81. package/lib/types/AttachmentMiddleware.d.ts +2 -2
  82. package/lib/types/AttachmentMiddleware.d.ts.map +1 -1
  83. package/lib/types/AvatarMiddleware.d.ts +2 -2
  84. package/lib/types/AvatarMiddleware.d.ts.map +1 -1
  85. package/lib/types/CardActionMiddleware.d.ts +1 -1
  86. package/lib/types/CardActionMiddleware.d.ts.map +1 -1
  87. package/lib/types/GroupActivitiesMiddleware.d.ts +7 -7
  88. package/lib/types/GroupActivitiesMiddleware.d.ts.map +1 -1
  89. package/lib/types/WebSpeechPonyfill.d.ts +1 -0
  90. package/lib/types/WebSpeechPonyfill.d.ts.map +1 -1
  91. package/package.json +24 -19
  92. package/src/StyleOptions.ts +2 -2
  93. package/src/hooks/Composer.tsx +4 -5
  94. package/src/hooks/internal/WebChatAPIContext.ts +3 -3
  95. package/src/hooks/middleware/createDefaultGroupActivitiesMiddleware.ts +18 -6
  96. package/src/hooks/useActiveTyping.ts +5 -3
  97. package/src/hooks/useActivities.ts +2 -2
  98. package/src/hooks/useCreateActivityStatusRenderer.tsx +56 -22
  99. package/src/hooks/useCreateAvatarRenderer.ts +2 -2
  100. package/src/hooks/useGetSendTimeoutForActivity.ts +3 -3
  101. package/src/hooks/useGroupActivities.ts +4 -4
  102. package/src/hooks/useMarkActivityAsSpoken.ts +2 -2
  103. package/src/hooks/usePostActivity.ts +2 -2
  104. package/src/hooks/useSendFiles.ts +8 -1
  105. package/src/hooks/useSendTimeoutForActivity.ts +2 -2
  106. package/src/hooks/useSuggestedActions.ts +1 -1
  107. package/src/hooks/useTimeoutForSend.ts +2 -2
  108. package/src/localization/en-US.json +5 -2
  109. package/src/providers/ActivityKeyer/ActivityKeyerComposer.tsx +7 -8
  110. package/src/providers/ActivityKeyer/private/Context.ts +3 -4
  111. package/src/providers/ActivityKeyer/private/getActivityId.ts +2 -2
  112. package/src/providers/ActivityKeyer/private/getClientActivityId.ts +2 -2
  113. package/src/providers/ActivityKeyer/useGetActivityByKey.ts +2 -2
  114. package/src/providers/ActivityKeyer/useGetKeyByActivity.ts +2 -2
  115. package/src/types/ActivityMiddleware.ts +3 -3
  116. package/src/types/ActivityStatusMiddleware.ts +3 -3
  117. package/src/types/AttachmentForScreenReaderMiddleware.ts +2 -2
  118. package/src/types/AttachmentMiddleware.ts +2 -2
  119. package/src/types/AvatarMiddleware.ts +2 -2
  120. package/src/types/CardActionMiddleware.ts +1 -1
  121. package/src/types/GroupActivitiesMiddleware.ts +7 -7
@@ -1,4 +1,4 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
3
  type StyleOptions = {
4
4
  /**
@@ -675,7 +675,7 @@ type StyleOptions = {
675
675
  */
676
676
  groupTimestamp?: boolean | number;
677
677
 
678
- sendTimeout?: number | ((activity: DirectLineActivity) => number);
678
+ sendTimeout?: number | ((activity: WebChatActivity) => number);
679
679
  sendTimeoutForAttachments?: number;
680
680
 
681
681
  /**
@@ -2,18 +2,14 @@ import { Provider } from 'react-redux';
2
2
  import PropTypes from 'prop-types';
3
3
  import React, { FC, ReactNode, useCallback, useEffect, useMemo, useRef, useState } from 'react';
4
4
  import updateIn from 'simple-update-in';
5
-
6
5
  import {
7
6
  clearSuggestedActions,
8
7
  connect as createConnectAction,
9
8
  createStore,
10
- DirectLineActivity,
11
- DirectLineJSBotConnection,
12
9
  disconnect,
13
10
  dismissNotification,
14
11
  emitTypingIndicator,
15
12
  markActivity,
16
- OneOrMany,
17
13
  postActivity,
18
14
  sendEvent,
19
15
  sendFiles,
@@ -34,6 +30,7 @@ import {
34
30
  stopSpeakingActivity,
35
31
  submitSendBox
36
32
  } from 'botframework-webchat-core';
33
+ import type { DirectLineJSBotConnection, OneOrMany, WebChatActivity } from 'botframework-webchat-core';
37
34
 
38
35
  import { default as WebChatAPIContext } from './internal/WebChatAPIContext';
39
36
  import ActivityAcknowledgementComposer from '../providers/ActivityAcknowledgement/ActivityAcknowledgementComposer';
@@ -199,7 +196,7 @@ type ComposerCoreProps = {
199
196
  overrideLocalizedStrings?: LocalizedStrings | ((strings: LocalizedStrings, language: string) => LocalizedStrings);
200
197
  renderMarkdown?: (markdown: string, { markdownRespectCRLF: boolean }, { externalLinkAlt: string }) => string;
201
198
  scrollToEndButtonMiddleware?: OneOrMany<ScrollToEndButtonMiddleware>;
202
- selectVoice?: (voices: typeof window.SpeechSynthesisVoice[], activity: DirectLineActivity) => void;
199
+ selectVoice?: (voices: typeof window.SpeechSynthesisVoice[], activity: WebChatActivity) => void;
203
200
  sendTypingIndicator?: boolean;
204
201
  styleOptions?: StyleOptions;
205
202
  toastMiddleware?: OneOrMany<ToastMiddleware>;
@@ -666,6 +663,8 @@ ComposerCore.propTypes = {
666
663
  cardActionMiddleware: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.func), PropTypes.func]),
667
664
  children: PropTypes.any,
668
665
  dir: PropTypes.oneOf(['auto', 'ltr', 'rtl']),
666
+ // PropTypes.shape({ ... }) did not honor isRequired for its members.
667
+ // @ts-ignore
669
668
  directLine: PropTypes.shape({
670
669
  activity$: PropTypes.shape({
671
670
  subscribe: PropTypes.func.isRequired
@@ -1,5 +1,5 @@
1
1
  import { createContext } from 'react';
2
- import { DirectLineActivity, DirectLineJSBotConnection } from 'botframework-webchat-core';
2
+ import type { DirectLineJSBotConnection, WebChatActivity } from 'botframework-webchat-core';
3
3
 
4
4
  import { AttachmentForScreenReaderComponentFactory } from '../../types/AttachmentForScreenReaderMiddleware';
5
5
  import { AvatarComponentFactory } from '../../types/AvatarMiddleware';
@@ -38,10 +38,10 @@ type WebChatAPIContext = {
38
38
  markActivity?: ({ id: string }, name: string, value?: any) => void;
39
39
  onCardAction?: PerformCardAction;
40
40
  onTelemetry?: (event: TelemetryMeasurementEvent) => void;
41
- postActivity?: (activity: DirectLineActivity) => Observable<string>;
41
+ postActivity?: (activity: WebChatActivity) => Observable<string>;
42
42
  renderMarkdown?: (markdown: string, { markdownRespectCRLF: boolean }, { externalLinkAlt: string }) => string;
43
43
  scrollToEndButtonRenderer?: ScrollToEndButtonComponentFactory;
44
- selectVoice?: (voices: typeof window.SpeechSynthesisVoice[], activity: DirectLineActivity) => void;
44
+ selectVoice?: (voices: typeof window.SpeechSynthesisVoice[], activity: WebChatActivity) => void;
45
45
  sendEvent?: (name: string, value: any) => void;
46
46
  sendFiles?: (files: File[]) => void;
47
47
  sendMessage?: (text: string, method?: string, { channelData }?: { channelData?: any }) => void;
@@ -1,9 +1,10 @@
1
- import { Constants, DirectLineActivity } from 'botframework-webchat-core';
1
+ import { Constants } from 'botframework-webchat-core';
2
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
3
 
3
4
  import GroupActivitiesMiddleware from '../../types/GroupActivitiesMiddleware';
4
5
 
5
6
  const {
6
- ActivityClientState: { SENT }
7
+ ActivityClientState: { SENDING, SEND_FAILED, SENT }
7
8
  } = Constants;
8
9
 
9
10
  function bin<T>(items: T[], grouping: (last: T, current: T) => boolean): T[][] {
@@ -25,13 +26,24 @@ function bin<T>(items: T[], grouping: (last: T, current: T) => boolean): T[][] {
25
26
  return bins;
26
27
  }
27
28
 
28
- function sending(activity: DirectLineActivity): boolean {
29
- return activity.from.role === 'user' && activity.channelData && activity.channelData.state !== SENT;
29
+ function sending(activity) {
30
+ if (activity.from.role === 'user') {
31
+ const state = activity.channelData?.state;
32
+
33
+ switch (state) {
34
+ case SENDING:
35
+ case SEND_FAILED:
36
+ return state;
37
+
38
+ default:
39
+ return SENT;
40
+ }
41
+ }
30
42
  }
31
43
 
32
44
  function shouldGroupTimestamp(
33
- activityX: DirectLineActivity,
34
- activityY: DirectLineActivity,
45
+ activityX: WebChatActivity,
46
+ activityY: WebChatActivity,
35
47
  groupTimestamp: boolean | number
36
48
  ): boolean {
37
49
  if (groupTimestamp === false) {
@@ -10,15 +10,17 @@ function useActiveTyping(expireAfter?: number): [{ [userId: string]: Typing }] {
10
10
 
11
11
  const [{ typingAnimationDuration }] = useStyleOptions();
12
12
  const forceRender = useForceRender();
13
- const typing: { [userId: string]: { at: number; name: string; role: string } } = useSelector(({ typing }) => typing);
13
+ const typing: { [userId: string]: { at: number; last: number; name: string; role: string } } = useSelector(
14
+ ({ typing }) => typing
15
+ );
14
16
 
15
17
  if (typeof expireAfter !== 'number') {
16
18
  expireAfter = typingAnimationDuration;
17
19
  }
18
20
 
19
21
  const activeTyping: { [userId: string]: Typing } = Object.entries(typing).reduce(
20
- (activeTyping, [id, { at, name, role }]) => {
21
- const until = at + expireAfter;
22
+ (activeTyping, [id, { at, last, name, role }]) => {
23
+ const until = last + expireAfter;
22
24
 
23
25
  if (until > now) {
24
26
  return { ...activeTyping, [id]: { at, expireAt: until, name, role } };
@@ -1,7 +1,7 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
3
  import { useSelector } from './internal/WebChatReduxContext';
4
4
 
5
- export default function useActivities(): [DirectLineActivity[]] {
5
+ export default function useActivities(): [WebChatActivity[]] {
6
6
  return [useSelector(({ activities }) => activities)];
7
7
  }
@@ -1,10 +1,11 @@
1
1
  /* eslint react/prop-types: "off" */
2
2
  /* eslint react/require-default-props: "off" */
3
3
 
4
- import { Constants, DirectLineActivity } from 'botframework-webchat-core';
5
- import React, { ReactNode, useMemo } from 'react';
4
+ import { Constants } from 'botframework-webchat-core';
5
+ import PropTypes from 'prop-types';
6
+ import React, { ReactNode, useMemo, VFC } from 'react';
7
+ import type { WebChatActivity } from 'botframework-webchat-core';
6
8
 
7
- import SendState from '../types/SendState';
8
9
  import useGetSendTimeoutForActivity from './useGetSendTimeoutForActivity';
9
10
  import useTimePassed from './internal/useTimePassed';
10
11
  import useWebChatAPIContext from './internal/useWebChatAPIContext';
@@ -13,32 +14,48 @@ const {
13
14
  ActivityClientState: { SEND_FAILED, SENDING, SENT }
14
15
  } = Constants;
15
16
 
16
- const ActivityStatusContainer = ({ activity, hideTimestamp, nextVisibleActivity }) => {
17
+ type ActivityStatusContainerProps = {
18
+ activity: WebChatActivity;
19
+ hideTimestamp: boolean;
20
+ nextVisibleActivity: WebChatActivity;
21
+ };
22
+
23
+ const ActivityStatusContainer: VFC<ActivityStatusContainerProps> = ({
24
+ activity,
25
+ hideTimestamp,
26
+ nextVisibleActivity
27
+ }) => {
17
28
  const { activityStatusRenderer: createActivityStatusRenderer } = useWebChatAPIContext();
18
29
  const getSendTimeoutForActivity = useGetSendTimeoutForActivity();
19
30
 
20
31
  // SEND_FAILED from the activity is ignored, and is instead based on styleOptions.sendTimeout.
21
32
  // Note that the derived state is time-sensitive. The useTimePassed() hook is used to make sure it changes over time.
22
33
  const {
23
- channelData: { clientTimestamp = 0, state } = {},
24
34
  from: { role }
25
- }: {
26
- channelData: {
27
- clientTimestamp?: number;
28
- state?: SendState;
29
- };
30
- from: {
31
- role: string;
32
- };
33
- } = activity;
34
-
35
- const activitySent = state !== SENDING && state !== SEND_FAILED;
35
+ }: WebChatActivity = activity;
36
+
36
37
  const fromUser = role === 'user';
37
- const sendTimeout = getSendTimeoutForActivity({ activity });
38
+ let activitySent: boolean;
39
+ let sendTimeoutAt: number;
40
+
41
+ if (fromUser) {
42
+ const state = activity.channelData?.state;
43
+ const sendTimeout = getSendTimeoutForActivity({ activity });
44
+
45
+ activitySent = state !== SENDING && state !== SEND_FAILED;
38
46
 
39
- const pastTimeout = useTimePassed(fromUser && !activitySent ? new Date(clientTimestamp).getTime() + sendTimeout : 0);
47
+ // If no timestamp, we assume the "sending" will be timed out as "send failed".
48
+ sendTimeoutAt = !activitySent
49
+ ? new Date(activity.localTimestamp || new Date(0).toISOString()).getTime() + sendTimeout
50
+ : 0;
51
+ } else {
52
+ activitySent = true;
53
+ sendTimeoutAt = 0;
54
+ }
40
55
 
41
- const sendState = activitySent || !fromUser ? SENT : pastTimeout ? SEND_FAILED : SENDING;
56
+ const pastTimeout = useTimePassed(sendTimeoutAt);
57
+
58
+ const sendState = activitySent ? SENT : pastTimeout ? SEND_FAILED : SENDING;
42
59
 
43
60
  return useMemo(
44
61
  () =>
@@ -53,13 +70,30 @@ const ActivityStatusContainer = ({ activity, hideTimestamp, nextVisibleActivity
53
70
  );
54
71
  };
55
72
 
73
+ ActivityStatusContainer.defaultProps = {
74
+ hideTimestamp: false,
75
+ nextVisibleActivity: undefined
76
+ };
77
+
78
+ ActivityStatusContainer.propTypes = {
79
+ // PropTypes cannot fully capture TypeScript types.
80
+ // @ts-ignore
81
+ activity: PropTypes.shape({
82
+ channelData: PropTypes.shape({ state: PropTypes.string }),
83
+ from: PropTypes.shape({ role: PropTypes.string }).isRequired,
84
+ localTimestamp: PropTypes.string
85
+ }).isRequired,
86
+ hideTimestamp: PropTypes.bool,
87
+ nextVisibleActivity: PropTypes.any
88
+ };
89
+
56
90
  export default function useCreateActivityStatusRenderer(): (renderOptions: {
57
- activity: DirectLineActivity;
58
- nextVisibleActivity: DirectLineActivity;
91
+ activity: WebChatActivity;
92
+ nextVisibleActivity: WebChatActivity;
59
93
  }) => (props: { hideTimestamp?: boolean }) => ReactNode {
60
94
  return useMemo(
61
95
  () =>
62
- ({ activity, nextVisibleActivity }: { activity: DirectLineActivity; nextVisibleActivity: DirectLineActivity }) =>
96
+ ({ activity, nextVisibleActivity }: { activity: WebChatActivity; nextVisibleActivity: WebChatActivity }) =>
63
97
  ({ hideTimestamp }: { hideTimestamp?: boolean } = {}) =>
64
98
  (
65
99
  <ActivityStatusContainer
@@ -1,5 +1,5 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
2
1
  import { useMemo } from 'react';
2
+ import type { WebChatActivity } from 'botframework-webchat-core';
3
3
 
4
4
  import { AvatarComponentFactory } from '../types/AvatarMiddleware';
5
5
  import useStyleOptions from './useStyleOptions';
@@ -8,7 +8,7 @@ import useWebChatAPIContext from './internal/useWebChatAPIContext';
8
8
  export default function useCreateAvatarRenderer(): ({
9
9
  activity
10
10
  }: {
11
- activity: DirectLineActivity;
11
+ activity: WebChatActivity;
12
12
  }) => AvatarComponentFactory {
13
13
  const [styleOptions] = useStyleOptions();
14
14
  const { avatarRenderer } = useWebChatAPIContext();
@@ -1,9 +1,9 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
2
1
  import { useMemo } from 'react';
2
+ import type { WebChatActivity } from 'botframework-webchat-core';
3
3
 
4
4
  import useStyleOptions from './useStyleOptions';
5
5
 
6
- export default function useGetSendTimeoutForActivity(): ({ activity }: { activity: DirectLineActivity }) => number {
6
+ export default function useGetSendTimeoutForActivity(): ({ activity }: { activity: WebChatActivity }) => number {
7
7
  const [{ sendTimeout, sendTimeoutForAttachments }] = useStyleOptions();
8
8
 
9
9
  return useMemo(
@@ -13,7 +13,7 @@ export default function useGetSendTimeoutForActivity(): ({ activity }: { activit
13
13
  return sendTimeout(activity);
14
14
  }
15
15
 
16
- return activity.attachments && activity.attachments.length ? sendTimeoutForAttachments : sendTimeout;
16
+ return activity.type === 'message' && activity.attachments?.length ? sendTimeoutForAttachments : sendTimeout;
17
17
  },
18
18
  [sendTimeout, sendTimeoutForAttachments]
19
19
  );
@@ -1,10 +1,10 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
3
  import useWebChatAPIContext from './internal/useWebChatAPIContext';
4
4
 
5
- export default function useGroupActivities(): ({ activities }: { activities: DirectLineActivity[] }) => {
6
- sender: DirectLineActivity[][];
7
- status: DirectLineActivity[][];
5
+ export default function useGroupActivities(): ({ activities }: { activities: WebChatActivity[] }) => {
6
+ sender: WebChatActivity[][];
7
+ status: WebChatActivity[][];
8
8
  } {
9
9
  return useWebChatAPIContext().groupActivities;
10
10
  }
@@ -1,9 +1,9 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
2
1
  import { useCallback } from 'react';
2
+ import type { WebChatActivity } from 'botframework-webchat-core';
3
3
 
4
4
  import useMarkActivity from './internal/useMarkActivity';
5
5
 
6
- export default function useMarkActivityAsSpoken(): (activity: DirectLineActivity) => void {
6
+ export default function useMarkActivityAsSpoken(): (activity: WebChatActivity) => void {
7
7
  const markActivity = useMarkActivity();
8
8
 
9
9
  return useCallback(activity => markActivity(activity, 'speak', false), [markActivity]);
@@ -1,8 +1,8 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
2
1
  import Observable from 'core-js/features/observable';
2
+ import type { WebChatActivity } from 'botframework-webchat-core';
3
3
 
4
4
  import useWebChatAPIContext from './internal/useWebChatAPIContext';
5
5
 
6
- export default function usePostActivity(): (activity: DirectLineActivity) => Observable<string> {
6
+ export default function usePostActivity(): (activity: WebChatActivity) => Observable<string> {
7
7
  return useWebChatAPIContext().postActivity;
8
8
  }
@@ -5,7 +5,14 @@ import { useCallback } from 'react';
5
5
  import useTrackEvent from './useTrackEvent';
6
6
  import useWebChatAPIContext from './internal/useWebChatAPIContext';
7
7
 
8
- export default function useSendFiles(): (files: File[]) => void {
8
+ type PostActivityFile = {
9
+ name: string;
10
+ size: number;
11
+ thumbnail?: string;
12
+ url: string;
13
+ };
14
+
15
+ export default function useSendFiles(): (files: PostActivityFile[]) => void {
9
16
  const { sendFiles } = useWebChatAPIContext();
10
17
  const trackEvent = useTrackEvent();
11
18
 
@@ -1,11 +1,11 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
3
  import useGetSendTimeoutForActivity from './useGetSendTimeoutForActivity';
4
4
 
5
5
  let showDeprecationNotes = true;
6
6
 
7
7
  /** @deprecated Please use "useGetSendTimeoutForActivity()" instead. */
8
- export default function useSendTimeoutForActivity(activity: DirectLineActivity) {
8
+ export default function useSendTimeoutForActivity(activity: WebChatActivity) {
9
9
  if (showDeprecationNotes) {
10
10
  console.warn(
11
11
  'botframework-webchat: "useSendTimeoutForActivity" is deprecated and will be removed on or after 2022-07-28. Please use "useGetSendTimeoutForActivity()" instead.'
@@ -1,5 +1,5 @@
1
- import { DirectLineSuggestedAction } from 'botframework-webchat-core';
2
1
  import { useCallback } from 'react';
2
+ import type { DirectLineSuggestedAction } from 'botframework-webchat-core';
3
3
 
4
4
  import { useSelector } from './internal/WebChatReduxContext';
5
5
  import useWebChatAPIContext from './internal/useWebChatAPIContext';
@@ -1,8 +1,8 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
3
  import useStyleOptions from './useStyleOptions';
4
4
 
5
- export default function useTimeoutForSend(): [number | ((activity: DirectLineActivity) => number)] {
5
+ export default function useTimeoutForSend(): [number | ((activity: WebChatActivity) => number)] {
6
6
  const [{ sendTimeout }] = useStyleOptions();
7
7
 
8
8
  return [sendTimeout];
@@ -18,7 +18,7 @@
18
18
  "ACTIVITY_YOU_ATTACHED_ALT": "You attached:",
19
19
  "_ACTIVITY_YOU_ATTACHED_ALT.comment": "This is for screen reader and is narrated before each attachments sent by the user.",
20
20
  "ACTIVITY_NUM_ATTACHMENTS_ONE_ALT": "1 attachment.",
21
- "_ACTIVITY_NUM_ATTACHMENTS_OONE_ALT.comment": "This is for screen reader and only narrated when the message arrive. The narration when the message arrive, could be \"Bot WC said: Hello, World! 1 attachment. Sent at 2020-01-02 12:34 PM.\". This is for plural rule of \"one\".",
21
+ "_ACTIVITY_NUM_ATTACHMENTS_ONE_ALT.comment": "This is for screen reader and only narrated when the message arrive. The narration when the message arrive, could be \"Bot WC said: Hello, World! 1 attachment. Sent at 2020-01-02 12:34 PM.\". This is for plural rule of \"one\".",
22
22
  "ACTIVITY_NUM_ATTACHMENTS_FEW_ALT": "$1 attachments.",
23
23
  "_ACTIVITY_NUM_ATTACHMENTS_FEW_ALT.comment": "$1 is the number of attachments. This is for plural rule of \"few\".",
24
24
  "ACTIVITY_NUM_ATTACHMENTS_MANY_ALT": "$1 attachments.",
@@ -137,5 +137,8 @@
137
137
  "TRANSCRIPT_NEW_MESSAGES": "New messages",
138
138
  "TRANSCRIPT_TERMINATOR_TEXT": "End of chat history",
139
139
  "TYPING_INDICATOR_ALT": "Showing typing indicator",
140
- "_TYPING_INDICATOR_ALT.comment": "This is for screen reader for the label that will be narrated when the other party is typing a message."
140
+ "_TYPING_INDICATOR_SINGLE_TEXT.comment": "This shows when a single user is typing.",
141
+ "TYPING_INDICATOR_SINGLE_TEXT": "$1 is typing.",
142
+ "_TYPING_INDICATOR_MULTIPLE_TEXT.comment": "This shows when two or more users are typing simultaneously.",
143
+ "TYPING_INDICATOR_MULTIPLE_TEXT": "$1 and others are typing."
141
144
  }
@@ -1,8 +1,7 @@
1
1
  import PropTypes from 'prop-types';
2
2
  import React, { useCallback, useMemo, useRef } from 'react';
3
-
4
- import type { DirectLineActivity } from 'botframework-webchat-core';
5
3
  import type { FC } from 'react';
4
+ import type { WebChatActivity } from 'botframework-webchat-core';
6
5
 
7
6
  import ActivityKeyerContext, { ActivityKeyerContextType } from './private/Context';
8
7
  import getActivityId from './private/getActivityId';
@@ -12,9 +11,9 @@ import useActivities from '../../hooks/useActivities';
12
11
  import useActivityKeyerContext from './private/useContext';
13
12
 
14
13
  type ActivityIdToKeyMap = Map<string, string>;
15
- type ActivityToKeyMap = Map<DirectLineActivity, string>;
14
+ type ActivityToKeyMap = Map<WebChatActivity, string>;
16
15
  type ClientActivityIdToKeyMap = Map<string, string>;
17
- type KeyToActivityMap = Map<string, DirectLineActivity>;
16
+ type KeyToActivityMap = Map<string, WebChatActivity>;
18
17
 
19
18
  /**
20
19
  * React context composer component to assign a perma-key to every activity.
@@ -80,13 +79,13 @@ const ActivityKeyerComposer: FC<{}> = ({ children }) => {
80
79
  return Object.freeze([Object.freeze(nextActivityKeys)]) as readonly [readonly string[]];
81
80
  }, [activities, activityIdToKeyMapRef, activityToKeyMapRef, clientActivityIdToKeyMapRef, keyToActivityMapRef]);
82
81
 
83
- const getActivityByKey: (key?: string) => DirectLineActivity | undefined = useCallback(
84
- (key?: string): DirectLineActivity | undefined => key && keyToActivityMapRef.current.get(key),
82
+ const getActivityByKey: (key?: string) => undefined | WebChatActivity = useCallback(
83
+ (key?: string): undefined | WebChatActivity => key && keyToActivityMapRef.current.get(key),
85
84
  [keyToActivityMapRef]
86
85
  );
87
86
 
88
- const getKeyByActivity: (activity?: DirectLineActivity) => string | undefined = useCallback(
89
- (activity?: DirectLineActivity) => activity && activityToKeyMapRef.current.get(activity),
87
+ const getKeyByActivity: (activity?: WebChatActivity) => string | undefined = useCallback(
88
+ (activity?: WebChatActivity) => activity && activityToKeyMapRef.current.get(activity),
90
89
  [activityToKeyMapRef]
91
90
  );
92
91
 
@@ -1,11 +1,10 @@
1
1
  import { createContext } from 'react';
2
-
3
- import type { DirectLineActivity } from 'botframework-webchat-core';
2
+ import type { WebChatActivity } from 'botframework-webchat-core';
4
3
 
5
4
  type ActivityKeyerContextType = {
6
5
  activityKeysState: readonly [readonly string[]];
7
- getActivityByKey: (key?: string) => DirectLineActivity | undefined;
8
- getKeyByActivity: (activity?: DirectLineActivity) => string | undefined;
6
+ getActivityByKey: (key?: string) => undefined | WebChatActivity;
7
+ getKeyByActivity: (activity?: WebChatActivity) => string | undefined;
9
8
  getKeyByActivityId: (activityKey?: string) => string | undefined;
10
9
  };
11
10
 
@@ -1,5 +1,5 @@
1
- import type { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
- export default function getActivityId(activity: DirectLineActivity): string {
3
+ export default function getActivityId(activity: WebChatActivity): string {
4
4
  return activity.id;
5
5
  }
@@ -1,5 +1,5 @@
1
- import type { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
- export default function getClientActivityId(activity: DirectLineActivity): string {
3
+ export default function getClientActivityId(activity: WebChatActivity): string {
4
4
  return activity.channelData?.clientActivityID;
5
5
  }
@@ -1,7 +1,7 @@
1
- import type { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
3
  import useActivityKeyerContext from './private/useContext';
4
4
 
5
- export default function useGetActivityByKey(): (key?: string) => DirectLineActivity | undefined {
5
+ export default function useGetActivityByKey(): (key?: string) => undefined | WebChatActivity {
6
6
  return useActivityKeyerContext().getActivityByKey;
7
7
  }
@@ -1,7 +1,7 @@
1
- import type { DirectLineActivity } from 'botframework-webchat-core';
1
+ import type { WebChatActivity } from 'botframework-webchat-core';
2
2
 
3
3
  import useActivityKeyerContext from './private/useContext';
4
4
 
5
- export default function useGetKeyByActivity(): (activity?: DirectLineActivity) => string | undefined {
5
+ export default function useGetKeyByActivity(): (activity?: WebChatActivity) => string | undefined {
6
6
  return useActivityKeyerContext().getKeyByActivity;
7
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: DirectLineActivity;
18
- nextVisibleActivity: DirectLineActivity;
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: DirectLineActivity;
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: DirectLineActivity;
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 { DirectLineActivity, DirectLineAttachment } from 'botframework-webchat-core';
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: DirectLineActivity;
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: DirectLineActivity;
5
+ activity: WebChatActivity;
6
6
  attachment: DirectLineAttachment;
7
7
  };
8
8
 
@@ -1,11 +1,11 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
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: DirectLineActivity;
8
+ activity: WebChatActivity;
9
9
  fromUser: boolean;
10
10
  styleOptions: StrictStyleOptions;
11
11
  }
@@ -1,4 +1,4 @@
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
 
@@ -1,21 +1,21 @@
1
- import { DirectLineActivity } from 'botframework-webchat-core';
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: DirectLineActivity[] }],
6
+ [{ activities: WebChatActivity[] }],
7
7
  {
8
- sender: DirectLineActivity[][];
9
- status: DirectLineActivity[][];
8
+ sender: WebChatActivity[][];
9
+ status: WebChatActivity[][];
10
10
  }
11
11
  >;
12
12
 
13
13
  type GroupActivitiesMiddleware = FunctionMiddleware<
14
14
  [],
15
- [{ activities: DirectLineActivity[] }],
15
+ [{ activities: WebChatActivity[] }],
16
16
  {
17
- sender: DirectLineActivity[][];
18
- status: DirectLineActivity[][];
17
+ sender: WebChatActivity[][];
18
+ status: WebChatActivity[][];
19
19
  }
20
20
  >;
21
21