Skip to content

Commit 8970778

Browse files
committed
Revert "Usability improvements"
This reverts commit 6d06e58.
1 parent 917cb13 commit 8970778

File tree

7 files changed

+45
-137
lines changed

7 files changed

+45
-137
lines changed

src/components/AnimatedStatusIcon.tsx

Lines changed: 14 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@ export interface AnimatedStatusIconProps {
2929
isTyping?: boolean;
3030
/** Whether there's an error */
3131
isError?: boolean;
32-
/** Volume level (0-1) for volume-responsive animations */
33-
volumeLevel?: number;
3432
/** Base color for inactive bars */
3533
baseColor?: string;
3634
/** Override animation type */
@@ -63,7 +61,6 @@ const AnimatedStatusIcon: React.FC<AnimatedStatusIconProps> = ({
6361
isSpeaking,
6462
isTyping,
6563
isError,
66-
volumeLevel = 0,
6764
baseColor = '#9CA3AF',
6865
animationType: overrideAnimationType,
6966
animationSpeed: overrideAnimationSpeed,
@@ -229,97 +226,30 @@ const AnimatedStatusIcon: React.FC<AnimatedStatusIconProps> = ({
229226
}
230227

231228
case 'scale': {
232-
// Speech pattern animation - each bar reacts differently to volume
229+
// Scale animation for line layout
233230
if (useLineLayout && 'delay' in bar) {
234231
const lineBar = bar as LineBar;
232+
const cycleTime = (time + lineBar.delay) % 1;
233+
const scaleTime = cycleTime < 0.5 ? cycleTime * 2 : 2 - cycleTime * 2;
235234

236-
// Use volume level to determine overall activity
237-
const volumeIntensity = Math.max(0, Math.min(1, volumeLevel));
238-
239-
// Each bar has different sensitivity and frequency response
240-
const barCharacteristics = [
241-
{ sensitivity: 0.8, frequency: 1.2, baseActivity: 0.3 }, // Bar 0 - Low freq, less sensitive
242-
{ sensitivity: 1.0, frequency: 1.8, baseActivity: 0.4 }, // Bar 1 - Mid-low freq
243-
{ sensitivity: 1.2, frequency: 2.5, baseActivity: 0.5 }, // Bar 2 - Center, most responsive
244-
{ sensitivity: 1.0, frequency: 2.0, baseActivity: 0.4 }, // Bar 3 - Mid-high freq
245-
{ sensitivity: 0.9, frequency: 1.5, baseActivity: 0.35 }, // Bar 4 - High freq
246-
];
247-
248-
const barChar = barCharacteristics[index] || barCharacteristics[2];
249-
250-
// Create dynamic time-based variation for each bar
251-
const time = animationTime % 1;
252-
const barTime = (time * barChar.frequency) % 1;
253-
254-
// Generate pseudo-random speech-like pattern
255-
const speechPattern =
256-
Math.sin(barTime * 2 * Math.PI) * 0.3 +
257-
Math.sin(barTime * 6 * Math.PI) * 0.2 +
258-
Math.sin(barTime * 12 * Math.PI) * 0.1;
259-
260-
// Each bar responds differently based on volume and its characteristics
261-
const barResponse = volumeIntensity * barChar.sensitivity;
262-
263-
// Combine base activity, volume response, and speech pattern
264-
const activity = Math.max(
265-
0,
266-
Math.min(
267-
1,
268-
barChar.baseActivity +
269-
barResponse * 0.6 +
270-
speechPattern * volumeIntensity * 0.4
271-
)
272-
);
273-
274-
// Scale the bar height based on activity
275-
const heightScale = 0.7 + activity * 1.1; // Range from 0.7x to 1.8x
276-
const height = lineBar.baseHeight * heightScale;
277-
const y = 12 - height / 2;
278-
279-
// Opacity varies with activity
280-
const opacity = 0.4 + activity * 0.6;
235+
// Ease in-out cubic
236+
const easeInOutCubic = (t: number) => {
237+
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
238+
};
239+
240+
const easedTime = easeInOutCubic(scaleTime);
241+
// Scale from base height to max height while maintaining the relative proportions
242+
const scaleFactor = 1 + easedTime * 0.5; // Scale up to 1.5x
243+
const height = lineBar.baseHeight * scaleFactor;
244+
const y = 12 - height / 2; // Keep bars centered vertically
281245

282246
return {
283-
opacity,
247+
opacity: 1,
284248
height,
285249
y,
286250
transform: '',
287251
};
288252
}
289-
290-
// For circular layout, create a wave-like speech pattern
291-
if (!useLineLayout) {
292-
const volumeIntensity = Math.max(0, Math.min(1, volumeLevel));
293-
const time = animationTime % 1;
294-
295-
// Create different wave patterns for each bar
296-
const barAngle = (index / actualBarCount) * 2 * Math.PI;
297-
const wavePattern =
298-
Math.sin(time * 4 * Math.PI + barAngle) * 0.3 +
299-
Math.sin(time * 8 * Math.PI + barAngle * 2) * 0.2 +
300-
Math.sin(time * 16 * Math.PI + barAngle * 3) * 0.1;
301-
302-
// Each bar has different sensitivity based on position
303-
const positionSensitivity =
304-
0.7 + 0.3 * Math.sin(barAngle + Math.PI / 4);
305-
306-
const activity = Math.max(
307-
0,
308-
Math.min(
309-
1,
310-
0.3 +
311-
volumeIntensity * positionSensitivity * 0.5 +
312-
wavePattern * volumeIntensity * 0.2
313-
)
314-
);
315-
316-
return {
317-
opacity: 0.4 + activity * 0.6,
318-
transform:
319-
activity > 0.5 ? `scale(${1 + (activity - 0.5) * 0.4})` : '',
320-
};
321-
}
322-
323253
return { opacity: 1, transform: '' };
324254
}
325255

src/components/VapiWidget.tsx

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { sizeStyles, radiusStyles, positionStyles } from './constants';
88
import ConsentForm from './widget/ConsentForm';
99
import FloatingButton from './widget/FloatingButton';
1010
import WidgetHeader from './widget/WidgetHeader';
11-
import AnimatedStatusIcon from './AnimatedStatusIcon';
11+
import VolumeIndicator from './widget/conversation/VolumeIndicator';
1212
import ConversationMessage from './widget/conversation/Message';
1313
import EmptyConversation from './widget/conversation/EmptyState';
1414
import VoiceControls from './widget/controls/VoiceControls';
@@ -35,7 +35,7 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
3535
mainLabel = 'Talk with AI',
3636
startButtonText = 'Start',
3737
endButtonText = 'End Call',
38-
emptyVoiceMessage = 'Click the start button to begin a conversation',
38+
emptyVoiceMessage = 'Click the microphone to start talking',
3939
emptyVoiceActiveMessage = 'Listening...',
4040
emptyChatMessage = 'Type a message to start chatting',
4141
emptyHybridMessage = 'Use voice or text to communicate',
@@ -127,9 +127,8 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
127127
!showTranscript &&
128128
vapi.voice.isCallActive &&
129129
(mode === 'voice' || mode === 'hybrid');
130-
const showingEmptyState = !vapi.voice.isCallActive;
131130

132-
if (isEmpty || hideTranscript || showingEmptyState) {
131+
if (isEmpty || hideTranscript) {
133132
return {
134133
display: 'flex',
135134
alignItems: 'center',
@@ -254,26 +253,27 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
254253
};
255254

256255
const renderConversationArea = () => {
257-
if (vapi.voice.isCallActive) {
258-
const shouldShowTranscript =
259-
showTranscript || mode === 'chat' || mode === 'hybrid';
260-
261-
if (shouldShowTranscript) {
262-
return renderConversationMessages();
263-
} else {
264-
return (
265-
<AnimatedStatusIcon
266-
size={150}
267-
connectionStatus={vapi.voice.connectionStatus}
268-
isCallActive={vapi.voice.isCallActive}
269-
isSpeaking={vapi.voice.isSpeaking}
270-
isTyping={vapi.chat.isTyping}
271-
volumeLevel={vapi.voice.volumeLevel}
272-
baseColor={colors.accentColor}
273-
colors={colors.accentColor}
274-
/>
275-
);
276-
}
256+
const shouldShowTranscript =
257+
showTranscript ||
258+
mode === 'chat' ||
259+
(mode === 'hybrid' && !vapi.voice.isCallActive);
260+
261+
const shouldShowVolumeIndicator =
262+
!shouldShowTranscript && vapi.voice.isCallActive;
263+
264+
if (shouldShowTranscript) {
265+
return renderConversationMessages();
266+
}
267+
268+
if (shouldShowVolumeIndicator) {
269+
return (
270+
<VolumeIndicator
271+
volumeLevel={vapi.voice.volumeLevel}
272+
isCallActive={vapi.voice.isCallActive}
273+
isSpeaking={vapi.voice.isSpeaking}
274+
theme={styles.theme}
275+
/>
276+
);
277277
}
278278

279279
return (
@@ -371,7 +371,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
371371

372372
{/* Conversation Area */}
373373
<div
374-
className="vapi-conversation-area"
375374
style={{
376375
...getConversationAreaStyle(),
377376
...getConversationLayoutStyle(),
@@ -403,7 +402,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
403402
connectionStatus={vapi.voice.connectionStatus}
404403
isSpeaking={vapi.voice.isSpeaking}
405404
isTyping={vapi.chat.isTyping}
406-
volumeLevel={vapi.voice.volumeLevel}
407405
onClick={handleFloatingButtonClick}
408406
onToggleCall={handleToggleCall}
409407
mainLabel={mainLabel}

src/components/types.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ export interface FloatingButtonProps {
7474
connectionStatus: 'disconnected' | 'connecting' | 'connected';
7575
isSpeaking: boolean;
7676
isTyping: boolean;
77-
volumeLevel: number;
7877
onClick: () => void;
7978
onToggleCall?: () => void;
8079
mainLabel: string;

src/components/widget/FloatingButton.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ const FloatingButton: React.FC<FloatingButtonProps> = ({
88
connectionStatus,
99
isSpeaking,
1010
isTyping,
11-
volumeLevel,
1211
onClick,
1312
onToggleCall,
1413
mainLabel,
@@ -69,7 +68,6 @@ const FloatingButton: React.FC<FloatingButtonProps> = ({
6968
isTyping={isTyping}
7069
baseColor={colors.accentColor}
7170
colors={colors.accentColor}
72-
volumeLevel={volumeLevel}
7371
/>
7472

7573
{(styles.size === 'compact' || styles.size === 'full') &&

src/components/widget/conversation/Message.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ const MarkdownMessage: React.FC<MarkdownMessageProps> = ({
1111
<div className="markdown-content">
1212
<ReactMarkdown
1313
components={{
14-
p: ({ children }) => <p className="mb-3 last:mb-0">{children}</p>,
14+
p: ({ children }) => <p className="mb-1 last:mb-0">{children}</p>,
1515
ul: ({ children }) => (
16-
<ul className="list-disc list-inside mb-3 last:mb-0">{children}</ul>
16+
<ul className="list-disc list-inside mb-1 last:mb-0">{children}</ul>
1717
),
1818
ol: ({ children }) => (
19-
<ol className="list-decimal list-inside mb-3 last:mb-0">
19+
<ol className="list-decimal list-inside mb-1 last:mb-0">
2020
{children}
2121
</ol>
2222
),
@@ -57,7 +57,7 @@ const MarkdownMessage: React.FC<MarkdownMessageProps> = ({
5757
<h3 className="text-sm font-bold mb-1">{children}</h3>
5858
),
5959
blockquote: ({ children }) => (
60-
<blockquote className="border-l-2 pl-2 my-3 opacity-80">
60+
<blockquote className="border-l-2 pl-2 my-1 opacity-80">
6161
{children}
6262
</blockquote>
6363
),

src/styles/globals.css

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,3 @@
88
box-sizing: border-box;
99
}
1010
}
11-
12-
/* Hide scrollbar completely */
13-
.vapi-conversation-area {
14-
/* Firefox */
15-
scrollbar-width: none;
16-
}
17-
18-
/* Webkit browsers */
19-
.vapi-conversation-area::-webkit-scrollbar {
20-
display: none;
21-
}

tests/widget-embed.spec.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,7 @@ test.describe('VapiWidget Embed Tests', () => {
3535
// Verify the widget has created some content (React root or shadow DOM)
3636
const widgetInitialized = await page.evaluate(() => {
3737
const widget = document.querySelector('#vapi-widget-1');
38-
if (!widget) {
39-
return false;
40-
}
38+
if (!widget) return false;
4139
// Check for React root or any child elements
4240
return (
4341
widget.children.length > 0 ||
@@ -76,9 +74,7 @@ test.describe('VapiWidget Embed Tests', () => {
7674
// Verify the widget has been initialized
7775
const widgetInitialized = await page.evaluate(() => {
7876
const widget = document.querySelector('#vapi-widget-2');
79-
if (!widget) {
80-
return false;
81-
}
77+
if (!widget) return false;
8278
return (
8379
widget.children.length > 0 ||
8480
widget.shadowRoot !== null ||
@@ -115,9 +111,7 @@ test.describe('VapiWidget Embed Tests', () => {
115111
// Verify the custom element has been initialized
116112
const widgetInitialized = await page.evaluate(() => {
117113
const widget = document.querySelector('vapi-widget');
118-
if (!widget) {
119-
return false;
120-
}
114+
if (!widget) return false;
121115
return (
122116
widget.children.length > 0 ||
123117
widget.shadowRoot !== null ||

0 commit comments

Comments
 (0)