@envive-ai/react-widgets-v3 0.3.22 → 0.3.23

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 (74) hide show
  1. package/dist/debug/chatEmbed.cjs +1 -1
  2. package/dist/debug/chatEmbed.js +1 -1
  3. package/dist/debug/reportIssue.cjs +1 -1
  4. package/dist/debug/reportIssue.js +1 -1
  5. package/dist/hocs/withBaseWidget/withBaseWidget.d.cts +2 -2
  6. package/dist/hocs/withBaseWidget/withBaseWidget.d.ts +2 -2
  7. package/dist/packages/widgets/dist/SearchResults/SearchResultsWidget.d.ts +2 -2
  8. package/dist/packages/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.ts +2 -2
  9. package/dist/packages/widgets/dist/SuggestionBar/SuggestionBar.d.ts +2 -2
  10. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.cjs +34 -8
  11. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.cts +3 -3
  12. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.d.ts +3 -3
  13. package/dist/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.js +35 -9
  14. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.cjs +13 -5
  15. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.cts +3 -3
  16. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.d.ts +3 -3
  17. package/dist/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.js +13 -5
  18. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.cjs +32 -6
  19. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.cts +3 -3
  20. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.d.ts +3 -3
  21. package/dist/widgets/ChatPreviewWidget/ChatPreviewWidget.js +33 -7
  22. package/dist/widgets/FloatingChatWidget/FloatingChatWidget.cjs +12 -4
  23. package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.cts +2 -2
  24. package/dist/widgets/FloatingChatWidget/FloatingChatWidget.d.ts +2 -2
  25. package/dist/widgets/FloatingChatWidget/FloatingChatWidget.js +12 -4
  26. package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.cjs +2 -2
  27. package/dist/widgets/FloatingChatWidget/hooks/useAutoPopup.js +2 -2
  28. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.cjs +7 -1
  29. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.cts +2 -2
  30. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.d.ts +2 -2
  31. package/dist/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.js +7 -1
  32. package/dist/widgets/ProductCardWidget/ProductCardWidget.cjs +31 -5
  33. package/dist/widgets/ProductCardWidget/ProductCardWidget.d.cts +2 -2
  34. package/dist/widgets/ProductCardWidget/ProductCardWidget.d.ts +2 -2
  35. package/dist/widgets/ProductCardWidget/ProductCardWidget.js +31 -5
  36. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.cjs +33 -7
  37. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.cts +3 -3
  38. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.d.ts +3 -3
  39. package/dist/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.js +34 -8
  40. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.cjs +3 -3
  41. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.cts +2 -2
  42. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.d.ts +2 -2
  43. package/dist/widgets/PromptCarouselWidget/PromptCarouselWidget.js +3 -3
  44. package/dist/widgets/SocialProofFlowWidget/SocialProofFlowWidget.d.cts +2 -2
  45. package/dist/widgets/SocialProofWidget/SocialProofWidget.cjs +34 -8
  46. package/dist/widgets/SocialProofWidget/SocialProofWidget.d.cts +3 -3
  47. package/dist/widgets/SocialProofWidget/SocialProofWidget.d.ts +3 -3
  48. package/dist/widgets/SocialProofWidget/SocialProofWidget.js +35 -9
  49. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.cjs +2 -2
  50. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.cts +2 -2
  51. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.d.ts +2 -2
  52. package/dist/widgets/TitledPromptCarouselWidget/TitledPromptCarouselWidget.js +2 -2
  53. package/dist/widgets/TypingAnimationFlowWidget/TypingAnimationFlowWidget.d.cts +2 -2
  54. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.cjs +31 -5
  55. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.cts +3 -3
  56. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.d.ts +3 -3
  57. package/dist/widgets/TypingAnimationWidget/TypingAnimationWidget.js +32 -6
  58. package/dist/widgets/dist/SearchResults/SearchResultsWidget.d.cts +2 -2
  59. package/dist/widgets/dist/SearchZeroState/SearchZeroStateWidget.d.cts +2 -2
  60. package/dist/widgets/dist/SuggestionBar/SuggestionBar.d.cts +2 -2
  61. package/dist/widgets/hooks/useGetWidgetStatus.cjs +1 -1
  62. package/dist/widgets/hooks/useGetWidgetStatus.js +1 -1
  63. package/dist/widgets/utils/functions.cjs +1 -1
  64. package/dist/widgets/utils/functions.js +1 -1
  65. package/package.json +1 -1
  66. package/src/widgets/ChatPreviewComparisonWidget/ChatPreviewComparisonWidget.tsx +33 -0
  67. package/src/widgets/ChatPreviewLoadingWidget/ChatPreviewLoadingWidget.tsx +9 -1
  68. package/src/widgets/ChatPreviewWidget/ChatPreviewWidget.tsx +33 -0
  69. package/src/widgets/FloatingChatWidget/FloatingChatWidget.tsx +20 -2
  70. package/src/widgets/FullPageSalesAgentWidget/FullPageSalesAgentWidget.tsx +8 -0
  71. package/src/widgets/ProductCardWidget/ProductCardWidget.tsx +36 -2
  72. package/src/widgets/PromptButtonCarouselWithImageWidget/PromptButtonCarouselWithImageWidget.tsx +34 -1
  73. package/src/widgets/SocialProofWidget/SocialProofWidget.tsx +33 -0
  74. package/src/widgets/TypingAnimationWidget/TypingAnimationWidget.tsx +36 -2
@@ -4,13 +4,14 @@ import { getStringIdForText } from "../utils/functions.js";
4
4
  import { useCallback } from "react";
5
5
  import { EnviveMetricsEventName, useAmplitude } from "@envive-ai/react-hooks/contexts/amplitudeContext";
6
6
  import { jsx } from "react/jsx-runtime";
7
- import { useSalesAgent } from "@envive-ai/react-hooks/contexts/salesAgentContext";
8
7
  import { WidgetTypeV3 } from "@envive-ai/react-hooks/contexts/typesV3";
9
8
  import { useSetAtom } from "jotai";
10
- import { ChatElementDisplayLocationV3 } from "@envive-ai/react-hooks/application/models";
11
- import { useWidgetInteraction } from "@envive-ai/react-hooks/hooks/WidgetInteraction";
9
+ import { useFeatureFlagService } from "@envive-ai/react-hooks/contexts/featureFlagServiceContext";
10
+ import { ChatElementDisplayLocationV3, FeatureGates } from "@envive-ai/react-hooks/application/models";
11
+ import { useSalesAgent } from "@envive-ai/react-hooks/contexts/salesAgentContext";
12
12
  import { WidgetInteractionComponent, WidgetInteractionType } from "@envive-ai/react-hooks/hooks/WidgetInteraction/types";
13
13
  import { PromptCarouselRows, usePromptCarouselAnalytics } from "@envive-ai/react-toolkit-v3/PromptCarousel";
14
+ import { useWidgetInteraction } from "@envive-ai/react-hooks/hooks/WidgetInteraction";
14
15
  import { chatOnToggleAtom } from "@envive-ai/react-hooks/atoms/chat/chatState";
15
16
  import { PromptButtonVariant } from "@envive-ai/react-toolkit-v3/PromptButton/types";
16
17
  import { TypingAnimation } from "@envive-ai/react-toolkit-v3/TypingAnimation";
@@ -30,7 +31,7 @@ const mockHintText = "Ask me anything";
30
31
  const TypingAnimationWidgetHandler = (props) => {
31
32
  const { onTypedMessageSubmitted } = useSalesAgent();
32
33
  const onToggle = useSetAtom(chatOnToggleAtom);
33
- const { hardcopyContent, widgetConfig, uiConfig, isLoading, widgetConfigId } = props;
34
+ const { hardcopyContent, widgetConfig, uiConfig, isLoading } = props;
34
35
  const titleLabel = hardcopyContent?.values?.titleLabel || "";
35
36
  const headlineText = hardcopyContent?.values?.headlineText || "";
36
37
  const animatedTextSequence = hardcopyContent?.values?.animatedTextSequence || [];
@@ -47,6 +48,9 @@ const TypingAnimationWidgetHandler = (props) => {
47
48
  const showTextField = typingAnimationWidgetConfig?.showTextField !== false;
48
49
  const logoSrc = uiConfig?.lookAndFeel?.widgetLogoSrc;
49
50
  const hideLogo = uiConfig?.lookAndFeel?.hideWidgetLogo;
51
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
52
+ const { featureFlagService } = useFeatureFlagService();
53
+ const isVoiceInputEnabled = featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
50
54
  const { trackEvent } = useAmplitude();
51
55
  const { trackWidgetInteraction } = useWidgetInteraction();
52
56
  const { onClick: onPromptClicked, onDrag, onHover, onMouseDown, onMouseUp, onTouchStart, onTouchEnd } = usePromptCarouselAnalytics(WidgetInteractionComponent.EMBEDDED_WIDGET, (text) => {
@@ -87,6 +91,25 @@ const TypingAnimationWidgetHandler = (props) => {
87
91
  }
88
92
  });
89
93
  }, [onToggle]);
94
+ const handleTranscriptionStarted = useCallback(() => {
95
+ trackWidgetInteraction({
96
+ eventName: EnviveMetricsEventName.WidgetInteraction,
97
+ trigger: {
98
+ widget: WidgetInteractionComponent.EMBEDDED_WIDGET,
99
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED
100
+ }
101
+ });
102
+ }, []);
103
+ const handleTranscriptionCompleted = useCallback((transcript) => {
104
+ trackWidgetInteraction({
105
+ eventName: EnviveMetricsEventName.WidgetInteraction,
106
+ trigger: {
107
+ widget: WidgetInteractionComponent.EMBEDDED_WIDGET,
108
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
109
+ widget_interaction_data: { transcription: transcript }
110
+ }
111
+ });
112
+ }, []);
90
113
  return /* @__PURE__ */ jsx(TypingAnimation, {
91
114
  baseProps: { id },
92
115
  widgetContentProps: {
@@ -97,7 +120,8 @@ const TypingAnimationWidgetHandler = (props) => {
97
120
  hintText: isLoading ? mockHintText : hintText,
98
121
  textFieldAriaLabel,
99
122
  logoSrc: logoSrc ?? void 0,
100
- hideLogo: hideLogo ?? false
123
+ hideLogo: hideLogo ?? false,
124
+ voiceInputEnabled: isVoiceInputEnabled
101
125
  },
102
126
  widgetStyleProps: {
103
127
  widgetVariant,
@@ -115,7 +139,9 @@ const TypingAnimationWidgetHandler = (props) => {
115
139
  handleButtonMouseUp: onMouseUp,
116
140
  handleButtonTouchStart: onTouchStart,
117
141
  handleButtonTouchEnd: onTouchEnd,
118
- handleTextFieldClick
142
+ handleTextFieldClick,
143
+ onTranscriptionStarted: handleTranscriptionStarted,
144
+ onTranscriptionCompleted: handleTranscriptionCompleted
119
145
  }
120
146
  });
121
147
  };
@@ -1,8 +1,8 @@
1
- import * as react_jsx_runtime0 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime1 from "react/jsx-runtime";
2
2
 
3
3
  //#region ../widgets/dist/SearchResults/SearchResultsWidget.d.ts
4
4
  //#region src/SearchResults/SearchResultsWidget.d.ts
5
- declare const SearchResultsWidget: () => react_jsx_runtime0.JSX.Element;
5
+ declare const SearchResultsWidget: () => react_jsx_runtime1.JSX.Element;
6
6
  //#endregion
7
7
 
8
8
  //#endregion
@@ -1,4 +1,4 @@
1
- import * as react_jsx_runtime2 from "react/jsx-runtime";
1
+ import * as react_jsx_runtime3 from "react/jsx-runtime";
2
2
 
3
3
  //#region ../widgets/dist/SearchZeroState/SearchZeroStateWidget.d.ts
4
4
  //#region src/SearchZeroState/SearchZeroStateWidget.d.ts
@@ -11,7 +11,7 @@ declare const SearchZeroStateWidget: ({
11
11
  initialIsOpen,
12
12
  widgetConfigId,
13
13
  entryPointRef
14
- }: SearchZeroStateWidgetProps) => react_jsx_runtime2.JSX.Element;
14
+ }: SearchZeroStateWidgetProps) => react_jsx_runtime3.JSX.Element;
15
15
  //#endregion
16
16
 
17
17
  //#endregion
@@ -1,5 +1,5 @@
1
1
  import { SuggestionBarLocationForMetrics } from "./types.cjs";
2
- import * as react_jsx_runtime3 from "react/jsx-runtime";
2
+ import * as react_jsx_runtime2 from "react/jsx-runtime";
3
3
  import { SuggestionButtonVariant } from "@envive-ai/react-hooks/contexts/types";
4
4
  import { Message } from "postcss";
5
5
 
@@ -30,7 +30,7 @@ declare function SuggestionBar({
30
30
  buttonBorderRadius,
31
31
  handleReply,
32
32
  dataTestId
33
- }: Readonly<SuggestionBarProps>): react_jsx_runtime3.JSX.Element;
33
+ }: Readonly<SuggestionBarProps>): react_jsx_runtime2.JSX.Element;
34
34
  //#endregion
35
35
  //#endregion
36
36
  export { SuggestionBar };
@@ -1,8 +1,8 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
2
  const require_functions = require('../utils/functions.cjs');
3
3
  let react = require("react");
4
- let __envive_ai_react_hooks_atoms_chat = require("@envive-ai/react-hooks/atoms/chat");
5
4
  let jotai = require("jotai");
5
+ let __envive_ai_react_hooks_atoms_chat = require("@envive-ai/react-hooks/atoms/chat");
6
6
  let __envive_ai_react_hooks_atoms_chat_chatState = require("@envive-ai/react-hooks/atoms/chat/chatState");
7
7
 
8
8
  //#region src/widgets/hooks/useGetWidgetStatus.tsx
@@ -1,7 +1,7 @@
1
1
  import { isLoading, isProductComparison, userHasInteracted, userHasNotInteracted } from "../utils/functions.js";
2
2
  import { useMemo } from "react";
3
- import { chatAtom, lastAssistantMessageAtom } from "@envive-ai/react-hooks/atoms/chat";
4
3
  import { useAtomValue } from "jotai";
4
+ import { chatAtom, lastAssistantMessageAtom } from "@envive-ai/react-hooks/atoms/chat";
5
5
  import { responseStreamingAtom } from "@envive-ai/react-hooks/atoms/chat/chatState";
6
6
 
7
7
  //#region src/widgets/hooks/useGetWidgetStatus.tsx
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
2
- let __envive_ai_react_hooks_atoms_chat = require("@envive-ai/react-hooks/atoms/chat");
3
2
  let __envive_ai_react_hooks_application_models = require("@envive-ai/react-hooks/application/models");
3
+ let __envive_ai_react_hooks_atoms_chat = require("@envive-ai/react-hooks/atoms/chat");
4
4
  let __envive_ai_react_hooks_atoms_atomStore = require("@envive-ai/react-hooks/atoms/atomStore");
5
5
 
6
6
  //#region src/widgets/utils/functions.ts
@@ -1,5 +1,5 @@
1
- import { chatAtom, lastAssistantMessageAtom } from "@envive-ai/react-hooks/atoms/chat";
2
1
  import { MessageRole, MessageType } from "@envive-ai/react-hooks/application/models";
2
+ import { chatAtom, lastAssistantMessageAtom } from "@envive-ai/react-hooks/atoms/chat";
3
3
  import { getAtomStore } from "@envive-ai/react-hooks/atoms/atomStore";
4
4
 
5
5
  //#region src/widgets/utils/functions.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@envive-ai/react-widgets-v3",
3
- "version": "0.3.22",
3
+ "version": "0.3.23",
4
4
  "description": "React widget library v3 for Envive services.",
5
5
  "keywords": [
6
6
  "react",
@@ -6,9 +6,11 @@ import {
6
6
  } from '@envive-ai/react-hooks/contexts/typesV3';
7
7
  import { useChatToggle } from '@envive-ai/react-hooks/hooks/ChatToggle';
8
8
  import { useAtomValue } from 'jotai';
9
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
9
10
 
10
11
  import {
11
12
  ChatElementDisplayLocationV3,
13
+ FeatureGates,
12
14
  Suggestion,
13
15
  VariantTypeEnum,
14
16
  } from '@envive-ai/react-hooks/application/models';
@@ -89,6 +91,11 @@ const ChatPreviewComparisonWidgetHandler = (props: BaseWidgetProps) => {
89
91
 
90
92
  const hideLogo = uiConfig?.lookAndFeel?.hideWidgetLogo;
91
93
 
94
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
95
+ const { featureFlagService } = useFeatureFlagService();
96
+ const isVoiceInputEnabled =
97
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
98
+
92
99
  const handlePromptButtonClick = useCallback(
93
100
  (suggestion: Suggestion) => {
94
101
  onSuggestionClicked(
@@ -112,6 +119,29 @@ const ChatPreviewComparisonWidgetHandler = (props: BaseWidgetProps) => {
112
119
  });
113
120
  }, [openChat]);
114
121
 
122
+ const handleTranscriptionStarted = useCallback(() => {
123
+ trackWidgetInteraction({
124
+ eventName: EnviveMetricsEventName.WidgetInteraction,
125
+ trigger: {
126
+ widget: WidgetInteractionComponent.POST_INTERACTION_COMPARISON,
127
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED,
128
+ },
129
+ });
130
+ }, []);
131
+
132
+ const handleTranscriptionCompleted = useCallback((transcript: string) => {
133
+ trackWidgetInteraction({
134
+ eventName: EnviveMetricsEventName.WidgetInteraction,
135
+ trigger: {
136
+ widget: WidgetInteractionComponent.POST_INTERACTION_COMPARISON,
137
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
138
+ widget_interaction_data: {
139
+ transcription: transcript,
140
+ },
141
+ },
142
+ });
143
+ }, []);
144
+
115
145
  const handleLinkClick = (url: string) => {
116
146
  trackWidgetInteraction({
117
147
  eventName: EnviveMetricsEventName.WidgetInteraction,
@@ -156,6 +186,7 @@ const ChatPreviewComparisonWidgetHandler = (props: BaseWidgetProps) => {
156
186
  textFieldPlaceholderText: hardCopyContent?.textFieldPlaceholderText,
157
187
  images: images ?? [],
158
188
  logoSrc: logoSrc ?? undefined,
189
+ voiceInputEnabled: isVoiceInputEnabled,
159
190
  };
160
191
 
161
192
  const widgetEventProps: ChatPreviewComparisonProps['widgetEventProps'] = {
@@ -168,6 +199,8 @@ const ChatPreviewComparisonWidgetHandler = (props: BaseWidgetProps) => {
168
199
  handlePromptButtonTouchEnd: onTouchEnd,
169
200
  handleLinkClick,
170
201
  handleTextFieldClick,
202
+ onTranscriptionStarted: handleTranscriptionStarted,
203
+ onTranscriptionCompleted: handleTranscriptionCompleted,
171
204
  };
172
205
 
173
206
  return (
@@ -3,9 +3,11 @@ import {
3
3
  WidgetTypeV3,
4
4
  } from '@envive-ai/react-hooks/contexts/typesV3';
5
5
  import { useAtomValue } from 'jotai';
6
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
7
+ import { FeatureGates } from '@envive-ai/react-hooks/application/models';
6
8
 
7
- import { ChatPreviewLoading } from '@envive-ai/react-toolkit-v3/ChatPreviewLoading';
8
9
  import { chatPreviewLoadingDataAtom } from '@envive-ai/react-hooks/atoms/widget';
10
+ import { ChatPreviewLoading } from '@envive-ai/react-toolkit-v3/ChatPreviewLoading';
9
11
  import { BaseWidgetProps } from '../../hocs/withBaseWidget/types';
10
12
  import { withBaseWidget } from '../../hocs/withBaseWidget/withBaseWidget';
11
13
  import { PromptCarouselWidget } from '../PromptCarouselWidget/PromptCarouselWidget';
@@ -19,6 +21,7 @@ const ChatPreviewLoadingWidgetHandler = (props: BaseWidgetProps) => {
19
21
 
20
22
  const chatPreviewLoadingDataMap = useAtomValue(chatPreviewLoadingDataAtom);
21
23
  const chatPreviewLoadingData = chatPreviewLoadingDataMap[widgetConfigId] ?? undefined;
24
+ const { featureFlagService } = useFeatureFlagService();
22
25
 
23
26
  const isCacheEmpty =
24
27
  !chatPreviewLoadingData ||
@@ -48,6 +51,10 @@ const ChatPreviewLoadingWidgetHandler = (props: BaseWidgetProps) => {
48
51
  const hideTextField =
49
52
  chatPreviewLoadingWidgetConfig?.hideTextField ?? chatPreviewLoadingData?.hideTextField;
50
53
 
54
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
55
+ const isVoiceInputEnabled =
56
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
57
+
51
58
  return (
52
59
  <ChatPreviewLoading
53
60
  id={id}
@@ -58,6 +65,7 @@ const ChatPreviewLoadingWidgetHandler = (props: BaseWidgetProps) => {
58
65
  hideLogo={hideLogo}
59
66
  logoSrc={logoSrc}
60
67
  titleLabel={titleLabel}
68
+ voiceInputEnabled={isVoiceInputEnabled}
61
69
  />
62
70
  );
63
71
  };
@@ -3,11 +3,13 @@ import { useSalesAgent } from '@envive-ai/react-hooks/contexts/salesAgentContext
3
3
  import { ChatPreviewWidgetV3Config, WidgetTypeV3 } from '@envive-ai/react-hooks/contexts/typesV3';
4
4
  import { useChatToggle } from '@envive-ai/react-hooks/hooks/ChatToggle';
5
5
  import { useAtomValue } from 'jotai';
6
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
6
7
 
7
8
  import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
8
9
 
9
10
  import {
10
11
  ChatElementDisplayLocationV3,
12
+ FeatureGates,
11
13
  Suggestion,
12
14
  } from '@envive-ai/react-hooks/application/models';
13
15
  import {
@@ -70,6 +72,11 @@ const ChatPreviewWidgetHandler = (props: BaseWidgetProps) => {
70
72
 
71
73
  const hideLogo = uiConfig?.lookAndFeel?.hideWidgetLogo;
72
74
 
75
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
76
+ const { featureFlagService } = useFeatureFlagService();
77
+ const isVoiceInputEnabled =
78
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
79
+
73
80
  const handlePromptButtonClick = useCallback(
74
81
  (suggestion: Suggestion) => {
75
82
  onSuggestionClicked(suggestion, ChatElementDisplayLocationV3.CHAT_PREVIEW_PROMPT_BUTTON);
@@ -90,6 +97,29 @@ const ChatPreviewWidgetHandler = (props: BaseWidgetProps) => {
90
97
  });
91
98
  }, [openChat]);
92
99
 
100
+ const handleTranscriptionStarted = useCallback(() => {
101
+ trackWidgetInteraction({
102
+ eventName: EnviveMetricsEventName.WidgetInteraction,
103
+ trigger: {
104
+ widget: WidgetInteractionComponent.CHAT_PREVIEW,
105
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED,
106
+ },
107
+ });
108
+ }, []);
109
+
110
+ const handleTranscriptionCompleted = useCallback((transcript: string) => {
111
+ trackWidgetInteraction({
112
+ eventName: EnviveMetricsEventName.WidgetInteraction,
113
+ trigger: {
114
+ widget: WidgetInteractionComponent.CHAT_PREVIEW,
115
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
116
+ widget_interaction_data: {
117
+ transcription: transcript,
118
+ },
119
+ },
120
+ });
121
+ }, []);
122
+
93
123
  const handleLinkClick = (url: string) => {
94
124
  trackWidgetInteraction({
95
125
  eventName: EnviveMetricsEventName.WidgetInteraction,
@@ -128,6 +158,7 @@ const ChatPreviewWidgetHandler = (props: BaseWidgetProps) => {
128
158
  promptButtons: hardCopyContent?.promptButtons,
129
159
  textFieldPlaceholderText: hardCopyContent?.textFieldPlaceholderText,
130
160
  logoSrc: logoSrc ?? undefined,
161
+ voiceInputEnabled: isVoiceInputEnabled,
131
162
  };
132
163
 
133
164
  const widgetEventProps: ChatPreviewProps['widgetEventProps'] = {
@@ -140,6 +171,8 @@ const ChatPreviewWidgetHandler = (props: BaseWidgetProps) => {
140
171
  handlePromptButtonTouchEnd: onTouchEnd,
141
172
  handleLinkClick,
142
173
  handleTextFieldClick,
174
+ onTranscriptionStarted: handleTranscriptionStarted,
175
+ onTranscriptionCompleted: handleTranscriptionCompleted,
143
176
  };
144
177
 
145
178
  return (
@@ -1,4 +1,7 @@
1
- import { ChatElementDisplayLocationV3 } from '@envive-ai/react-hooks/application/models';
1
+ import {
2
+ ChatElementDisplayLocationV3,
3
+ FeatureGates,
4
+ } from '@envive-ai/react-hooks/application/models';
2
5
  import {
3
6
  EnviveMetricsEventName,
4
7
  useAmplitude,
@@ -12,6 +15,7 @@ import {
12
15
  import { useChatToggle } from '@envive-ai/react-hooks/hooks/ChatToggle';
13
16
  import { useTrackComponentVisibleEvent } from '@envive-ai/react-hooks/hooks/TrackComponentVisibleEvent';
14
17
  import { useWidgetInteraction } from '@envive-ai/react-hooks/hooks/WidgetInteraction';
18
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
15
19
  import {
16
20
  Collapse,
17
21
  WidgetInteractionComponent,
@@ -92,6 +96,20 @@ const FloatingChatWidgetHandler = (props: FloatingChatWidgetHandlerProps) => {
92
96
  (customerServiceIntegration?.provider as CustomerServiceType) ??
93
97
  CustomerServiceType.unsupported;
94
98
 
99
+ const { featureFlagService } = useFeatureFlagService();
100
+ const originalVoiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
101
+ const isVoiceInputEnabled =
102
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) ||
103
+ originalVoiceInputEnabled;
104
+
105
+ const modifiedLookAndFeelConfig = useMemo(
106
+ () => ({
107
+ ...uiConfig?.lookAndFeel,
108
+ voiceInputEnabled: isVoiceInputEnabled,
109
+ }),
110
+ [uiConfig?.lookAndFeel, isVoiceInputEnabled],
111
+ );
112
+
95
113
  // TODO: Get hardcopy content
96
114
  const { isOpen, openChat, closeChat, onHover } = useChatToggle();
97
115
 
@@ -186,7 +204,7 @@ const FloatingChatWidgetHandler = (props: FloatingChatWidgetHandlerProps) => {
186
204
  salesAgentData={salesAgentData}
187
205
  hardcopyContent={hardcopyContent}
188
206
  floatingChatConfig={uiConfig?.floatingChat ?? ({} as FloatingChatConfig)}
189
- lookAndFeelConfig={uiConfig?.lookAndFeel ?? ({} as LookAndFeelConfig)}
207
+ lookAndFeelConfig={modifiedLookAndFeelConfig ?? ({} as LookAndFeelConfig)}
190
208
  isCXButtonSwitchEnabled={!!isSwitchEnabled?.()}
191
209
  isFloatingChatOpen={effectiveIsOpen}
192
210
  onToggleCXButton={toggle}
@@ -7,6 +7,8 @@ import {
7
7
  import { FullPageSalesAgent } from '@envive-ai/react-toolkit-v3/FullPageSalesAgent';
8
8
  import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
9
9
  import { BaseWidgetProps, withBaseWidget } from 'src/hocs/withBaseWidget';
10
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
11
+ import { FeatureGates } from '@envive-ai/react-hooks/application/models';
10
12
 
11
13
  const FullPageSalesAgentHandler = ({
12
14
  uiConfig,
@@ -15,6 +17,11 @@ const FullPageSalesAgentHandler = ({
15
17
  }: BaseWidgetProps) => {
16
18
  const { headerContainer, autoHeight } = (widgetConfig as FullPageSalesAgentWidgetV3Config) || {};
17
19
 
20
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
21
+ const { featureFlagService } = useFeatureFlagService();
22
+ const isVoiceInputEnabled =
23
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
24
+
18
25
  return (
19
26
  <FullPageSalesAgent
20
27
  theme={Theme.STANDARD}
@@ -23,6 +30,7 @@ const FullPageSalesAgentHandler = ({
23
30
  hardcopyContent={hardcopyContent}
24
31
  headerContainer={headerContainer}
25
32
  autoHeight={autoHeight}
33
+ voiceInputEnabled={isVoiceInputEnabled}
26
34
  />
27
35
  );
28
36
  };
@@ -1,4 +1,7 @@
1
- import { ChatElementDisplayLocationV3 } from '@envive-ai/react-hooks/application/models';
1
+ import {
2
+ ChatElementDisplayLocationV3,
3
+ FeatureGates,
4
+ } from '@envive-ai/react-hooks/application/models';
2
5
  import {
3
6
  EnviveMetricsEventName,
4
7
  useAmplitude,
@@ -7,6 +10,7 @@ import { useSalesAgent } from '@envive-ai/react-hooks/contexts/salesAgentContext
7
10
  import { ProductCardWidgetV3Config, WidgetTypeV3 } from '@envive-ai/react-hooks/contexts/typesV3';
8
11
  import { useChatToggle } from '@envive-ai/react-hooks/hooks/ChatToggle';
9
12
  import { useWidgetInteraction } from '@envive-ai/react-hooks/hooks/WidgetInteraction';
13
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
10
14
  import {
11
15
  WidgetInteractionComponent,
12
16
  WidgetInteractionType,
@@ -33,7 +37,7 @@ const mockAnimatedText = ['Loading...'];
33
37
  const ProductCardWidgetHandler = (props: BaseWidgetProps) => {
34
38
  const { onTypedMessageSubmitted } = useSalesAgent();
35
39
  const { openChat } = useChatToggle();
36
- const { hardcopyContent, widgetConfig, isLoading } = props;
40
+ const { hardcopyContent, widgetConfig, uiConfig, isLoading } = props;
37
41
 
38
42
  const hardCopyHeadline = hardcopyContent?.values?.headline as string | undefined;
39
43
  const headline = isLoading ? mockHeadline : hardCopyHeadline || '';
@@ -55,6 +59,10 @@ const ProductCardWidgetHandler = (props: BaseWidgetProps) => {
55
59
  const italicizeHeadline = productCardWidgetConfig?.italicizeHeadline;
56
60
  const fallbackColor = productCardWidgetConfig?.fallbackColor;
57
61
  const imageSrc = productCardWidgetConfig?.imageSrc || '';
62
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
63
+ const { featureFlagService } = useFeatureFlagService();
64
+ const isVoiceInputEnabled =
65
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
58
66
 
59
67
  const { trackEvent } = useAmplitude();
60
68
  const { trackWidgetInteraction } = useWidgetInteraction();
@@ -105,6 +113,29 @@ const ProductCardWidgetHandler = (props: BaseWidgetProps) => {
105
113
  });
106
114
  }, [openChat]);
107
115
 
116
+ const handleTranscriptionStarted = useCallback(() => {
117
+ trackWidgetInteraction({
118
+ eventName: EnviveMetricsEventName.WidgetInteraction,
119
+ trigger: {
120
+ widget: WidgetInteractionComponent.IMAGE_PROMPT_CARD,
121
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED,
122
+ },
123
+ });
124
+ }, []);
125
+
126
+ const handleTranscriptionCompleted = useCallback((transcript: string) => {
127
+ trackWidgetInteraction({
128
+ eventName: EnviveMetricsEventName.WidgetInteraction,
129
+ trigger: {
130
+ widget: WidgetInteractionComponent.IMAGE_PROMPT_CARD,
131
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
132
+ widget_interaction_data: {
133
+ transcription: transcript,
134
+ },
135
+ },
136
+ });
137
+ }, []);
138
+
108
139
  return (
109
140
  <ProductCard
110
141
  theme={Theme.GLOBAL_CUSTOM}
@@ -117,6 +148,7 @@ const ProductCardWidgetHandler = (props: BaseWidgetProps) => {
117
148
  promptButtonType={promptButtonType}
118
149
  carouselId={carouselId}
119
150
  placeholder={placeholder}
151
+ voiceInputEnabled={isVoiceInputEnabled}
120
152
  textTypingDuration={800}
121
153
  textTransition={2000}
122
154
  onSelect={handleSelect}
@@ -127,6 +159,8 @@ const ProductCardWidgetHandler = (props: BaseWidgetProps) => {
127
159
  onTouchStart={onTouchStart}
128
160
  onTouchEnd={onTouchEnd}
129
161
  onInputClick={handleInputClick}
162
+ onTranscriptionStarted={handleTranscriptionStarted}
163
+ onTranscriptionCompleted={handleTranscriptionCompleted}
130
164
  />
131
165
  );
132
166
  };
@@ -4,9 +4,11 @@ import {
4
4
  WidgetTypeV3,
5
5
  } from '@envive-ai/react-hooks/contexts/typesV3';
6
6
  import { useChatToggle } from '@envive-ai/react-hooks/hooks/ChatToggle';
7
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
7
8
 
8
9
  import {
9
10
  ChatElementDisplayLocationV3,
11
+ FeatureGates,
10
12
  VariantTypeEnum,
11
13
  } from '@envive-ai/react-hooks/application/models';
12
14
  import { variantInfoAtom } from '@envive-ai/react-hooks/atoms/app';
@@ -46,7 +48,7 @@ const PromptButtonCarouselWithImageWidgetHandler = (props: BaseWidgetProps) => {
46
48
  onTouchEnd,
47
49
  } = usePromptCarouselAnalytics(WidgetInteractionComponent.SINGLE_IMAGE_PROMPT, text => text);
48
50
 
49
- const { hardcopyContent, widgetConfig, isLoading, widgetConfigId } = props;
51
+ const { hardcopyContent, widgetConfig, uiConfig, isLoading } = props;
50
52
 
51
53
  const promptButtonCarouselWithImageWidgetConfig =
52
54
  widgetConfig as PromptButtonCarouselWithImageWidgetV3Config;
@@ -99,6 +101,29 @@ const PromptButtonCarouselWithImageWidgetHandler = (props: BaseWidgetProps) => {
99
101
  });
100
102
  }, [openChat]);
101
103
 
104
+ const handleTranscriptionStarted = useCallback(() => {
105
+ trackWidgetInteraction({
106
+ eventName: EnviveMetricsEventName.WidgetInteraction,
107
+ trigger: {
108
+ widget: WidgetInteractionComponent.SINGLE_IMAGE_PROMPT,
109
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED,
110
+ },
111
+ });
112
+ }, []);
113
+
114
+ const handleTranscriptionCompleted = useCallback((transcript: string) => {
115
+ trackWidgetInteraction({
116
+ eventName: EnviveMetricsEventName.WidgetInteraction,
117
+ trigger: {
118
+ widget: WidgetInteractionComponent.SINGLE_IMAGE_PROMPT,
119
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
120
+ widget_interaction_data: {
121
+ transcription: transcript,
122
+ },
123
+ },
124
+ });
125
+ }, []);
126
+
102
127
  const variantInfo = useAtomValue(variantInfoAtom);
103
128
  const productId = variantInfo.variant === VariantTypeEnum.Pdp ? variantInfo.productId : undefined;
104
129
 
@@ -120,6 +145,11 @@ const PromptButtonCarouselWithImageWidgetHandler = (props: BaseWidgetProps) => {
120
145
  ? 'Product Image From Page'
121
146
  : promptButtonCarouselWithImageWidgetConfig?.image?.alt;
122
147
 
148
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
149
+ const { featureFlagService } = useFeatureFlagService();
150
+ const isVoiceInputEnabled =
151
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
152
+
123
153
  return (
124
154
  <PromptButtonCarouselWithImage
125
155
  id={id}
@@ -132,6 +162,7 @@ const PromptButtonCarouselWithImageWidgetHandler = (props: BaseWidgetProps) => {
132
162
  alt={finalImageAlt}
133
163
  textFieldPlaceholder={hardCopyContent?.textFieldPlaceholder}
134
164
  hideTextField={promptButtonCarouselWithImageWidgetConfig?.hideTextField}
165
+ voiceInputEnabled={isVoiceInputEnabled}
135
166
  handlePromptButtonClick={handlePromptButtonClick}
136
167
  handlePromptButtonDrag={onDrag}
137
168
  handlePromptButtonHover={onHover}
@@ -140,6 +171,8 @@ const PromptButtonCarouselWithImageWidgetHandler = (props: BaseWidgetProps) => {
140
171
  handlePromptButtonTouchStart={onTouchStart}
141
172
  handlePromptButtonTouchEnd={onTouchEnd}
142
173
  handleTextFieldClick={handleTextFieldClick}
174
+ onTranscriptionStarted={handleTranscriptionStarted}
175
+ onTranscriptionCompleted={handleTranscriptionCompleted}
143
176
  />
144
177
  );
145
178
  };
@@ -13,6 +13,7 @@ import {
13
13
 
14
14
  import {
15
15
  ChatElementDisplayLocationV3,
16
+ FeatureGates,
16
17
  VariantTypeEnum,
17
18
  } from '@envive-ai/react-hooks/application/models';
18
19
  import { chatPreviewLoadingDataAtom } from '@envive-ai/react-hooks/atoms/widget';
@@ -29,6 +30,7 @@ import { useProductImageUrl } from '@envive-ai/react-hooks/hooks/ProductImageUrl
29
30
  import { ChatPreviewLoading } from '@envive-ai/react-toolkit-v3/ChatPreviewLoading';
30
31
  import { usePromptCarouselAnalytics } from '@envive-ai/react-toolkit-v3/PromptCarousel';
31
32
  import { Theme } from '@envive-ai/react-toolkit-v3/Tokens';
33
+ import { useFeatureFlagService } from '@envive-ai/react-hooks/contexts/featureFlagServiceContext';
32
34
 
33
35
  import { BaseWidgetProps } from '../../hocs/withBaseWidget/types';
34
36
  import { withBaseWidget } from '../../hocs/withBaseWidget/withBaseWidget';
@@ -97,6 +99,11 @@ const SocialProofWidgetHandler = (props: BaseWidgetProps) => {
97
99
 
98
100
  const hideLogo = uiConfig?.lookAndFeel?.hideWidgetLogo;
99
101
 
102
+ const voiceInputEnabled = uiConfig?.lookAndFeel?.voiceInputEnabled;
103
+ const { featureFlagService } = useFeatureFlagService();
104
+ const isVoiceInputEnabled =
105
+ featureFlagService?.isFeatureGateEnabled(FeatureGates.IsVoiceInputEnabled) || voiceInputEnabled;
106
+
100
107
  const productId = variantInfo.variant === VariantTypeEnum.Pdp ? variantInfo.productId : undefined;
101
108
  const dynamicImageUrl = useProductImageUrl(productId);
102
109
 
@@ -191,6 +198,29 @@ const SocialProofWidgetHandler = (props: BaseWidgetProps) => {
191
198
  });
192
199
  }, [openChat]);
193
200
 
201
+ const handleTranscriptionStarted = useCallback(() => {
202
+ trackWidgetInteraction({
203
+ eventName: EnviveMetricsEventName.WidgetInteraction,
204
+ trigger: {
205
+ widget: WidgetInteractionComponent.SOCIAL_PROOF,
206
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_STARTED,
207
+ },
208
+ });
209
+ }, []);
210
+
211
+ const handleTranscriptionCompleted = useCallback((transcript: string) => {
212
+ trackWidgetInteraction({
213
+ eventName: EnviveMetricsEventName.WidgetInteraction,
214
+ trigger: {
215
+ widget: WidgetInteractionComponent.SOCIAL_PROOF,
216
+ widget_interaction: WidgetInteractionType.VOICE_TRANSCRIPTION_COMPLETED,
217
+ widget_interaction_data: {
218
+ transcription: transcript,
219
+ },
220
+ },
221
+ });
222
+ }, []);
223
+
194
224
  if (isLoading) {
195
225
  return <ChatPreviewLoading fullIsLoading />;
196
226
  }
@@ -233,6 +263,7 @@ const SocialProofWidgetHandler = (props: BaseWidgetProps) => {
233
263
  textFieldPlaceholderText: hardCopyContent?.textFieldPlaceholderText,
234
264
  images: images ?? [],
235
265
  logoSrc: logoSrc ?? undefined,
266
+ voiceInputEnabled: isVoiceInputEnabled,
236
267
  };
237
268
 
238
269
  const widgetEventProps: SocialProofProps['widgetEventProps'] = {
@@ -246,6 +277,8 @@ const SocialProofWidgetHandler = (props: BaseWidgetProps) => {
246
277
  handleSecondaryButtonTouchStart: onTouchStart,
247
278
  handleSecondaryButtonTouchEnd: onTouchEnd,
248
279
  handleTextFieldClick,
280
+ onTranscriptionStarted: handleTranscriptionStarted,
281
+ onTranscriptionCompleted: handleTranscriptionCompleted,
249
282
  };
250
283
 
251
284
  return (