Skip to content

Commit 3f65c55

Browse files
committed
cleaned up the files
1 parent 7d6ed3d commit 3f65c55

File tree

16 files changed

+72
-208
lines changed

16 files changed

+72
-208
lines changed

example/src/App.tsx

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import AnimatedStatusIconPreview from './components/AnimatedStatusIconPreview'
77
import type { WidgetConfig } from './types'
88
import VapiLogomark from '../logomark-primary.svg'
99

10-
// Import extracted components
1110
import NavigationTabs from './components/builder/NavigationTabs'
1211
import WidgetEmbedSection from './components/builder/WidgetEmbedSection'
1312
import ModeSection from './components/builder/ModeSection'
@@ -17,7 +16,6 @@ import TextLabelsSection from './components/builder/TextLabelsSection'
1716
import LegalConsentSection from './components/builder/LegalConsentSection'
1817
import VapiConfigurationSection from './components/builder/VapiConfigurationSection'
1918

20-
// Main App Component
2119
function App() {
2220
const [config, setConfig] = useState<WidgetConfig>({
2321
mode: 'voice',
@@ -66,7 +64,6 @@ function App() {
6664
setConfig(prev => ({ ...prev, [key]: value }))
6765
}
6866

69-
// Generate vapiConfig based on the selected type
7067
const generateVapiConfig = () => {
7168
try {
7269
switch (config.vapiConfigType) {

example/src/components/builder/VapiConfigurationSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ const VapiConfigurationSection: React.FC<VapiConfigurationSectionProps> = ({ con
1717
Configure how the widget connects to Vapi AI
1818
</p>
1919

20-
{/* Public Key - Always shown first */}
20+
{/* Public Key */}
2121
<div className="mb-6">
2222
<label className="block text-sm font-medium mb-2 text-gray-700">
2323
Vapi Public Key

example/src/types/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ export interface WidgetConfig {
1515
termsContent: string
1616
localStorageKey: string
1717
showTranscript: boolean
18+
1819
// Vapi Configuration
1920
publicKey: string
2021
vapiConfigType: 'assistantId' | 'assistantWithOverrides' | 'assistantObject'
2122
assistantId: string
2223
assistantOverrides: string
2324
assistantObject: string
24-
}
25+
}

src/components/AnimatedStatusIcon.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import React, { useState, useEffect } from 'react'
22

3-
// Type definitions for bar objects
43
type CircularBar = {
54
x: number
65
y: number

src/components/VapiWidget.tsx

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import React, { useState, useEffect, useRef } from 'react'
22
import { useVapiWidget } from '../hooks'
33

4-
// Import extracted types
54
import { VapiWidgetProps, ColorScheme, StyleConfig } from './types'
65

7-
// Import extracted constants
86
import { sizeClasses, radiusClasses, positionClasses } from './constants'
97

10-
// Import extracted components
118
import ConsentForm from './widget/ConsentForm'
129
import FloatingButton from './widget/FloatingButton'
1310
import WidgetHeader from './widget/WidgetHeader'
@@ -18,7 +15,6 @@ import VoiceControls from './widget/controls/VoiceControls'
1815
import ChatControls from './widget/controls/ChatControls'
1916
import HybridControls from './widget/controls/HybridControls'
2017

21-
// Import animations
2218
import '../styles/animations.css'
2319

2420
const VapiWidget: React.FC<VapiWidgetProps> = ({
@@ -54,13 +50,10 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
5450
const [hasConsent, setHasConsent] = useState(false)
5551
const [chatInput, setChatInput] = useState('')
5652

57-
// Ref for auto-scrolling
5853
const conversationEndRef = useRef<HTMLDivElement>(null)
5954

60-
// Ref for input field focus
6155
const inputRef = useRef<HTMLInputElement>(null)
6256

63-
// Use the new combined hook
6457
const vapi = useVapiWidget({
6558
mode,
6659
publicKey,
@@ -72,7 +65,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
7265
onError
7366
})
7467

75-
// Create color scheme object
7668
const colors: ColorScheme = {
7769
baseColor: baseColor
7870
? (theme === 'dark' && baseColor === '#FFFFFF' ? '#000000' : baseColor)
@@ -82,17 +74,14 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
8274
buttonAccentColor: buttonAccentColor || '#FFFFFF'
8375
}
8476

85-
// Adjust size for chat/hybrid modes - tiny behaves as medium
8677
const effectiveSize = mode !== 'voice' && size === 'tiny' ? 'compact' : size
8778

88-
// Create style config object
8979
const styles: StyleConfig = {
9080
size: effectiveSize,
9181
radius,
9282
theme
9383
}
9484

95-
// Check consent on mount
9685
useEffect(() => {
9786
if (requireConsent) {
9887
const storedConsent = localStorage.getItem(localStorageKey)
@@ -103,15 +92,12 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
10392
}
10493
}, [requireConsent, localStorageKey])
10594

106-
// Auto-scroll to bottom when new messages arrive or content streams
10795
useEffect(() => {
10896
conversationEndRef.current?.scrollIntoView({ behavior: 'smooth' })
10997
}, [vapi.conversation, vapi.chat.isTyping])
11098

111-
// Auto-focus input when widget expands in chat or hybrid mode
11299
useEffect(() => {
113100
if (isExpanded && (mode === 'chat' || mode === 'hybrid')) {
114-
// Small delay to ensure the DOM is ready
115101
setTimeout(() => {
116102
inputRef.current?.focus()
117103
}, 100)
@@ -121,11 +107,9 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
121107
const handleConsentAgree = () => {
122108
localStorage.setItem(localStorageKey, 'true')
123109
setHasConsent(true)
124-
// Widget will automatically show since isExpanded is already true
125110
}
126111

127112
const handleConsentCancel = () => {
128-
// Just close the expanded view
129113
setIsExpanded(false)
130114
}
131115

@@ -136,14 +120,11 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
136120
const handleSendMessage = async () => {
137121
if (!chatInput.trim()) return
138122

139-
// Store the message and clear input immediately
140123
const message = chatInput.trim()
141124
setChatInput('')
142125

143-
// Then send the message
144126
await vapi.chat.sendMessage(message)
145127

146-
// Maintain focus on the input field
147128
inputRef.current?.focus()
148129
}
149130

@@ -154,22 +135,18 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
154135
}
155136

156137
const handleReset = () => {
157-
// Clear all conversation history and session states
158138
vapi.clearConversation()
159139

160-
// If there's an active call, end it
161140
if (vapi.voice.isCallActive) {
162141
vapi.voice.endCall()
163142
}
164143

165-
// Clear the chat input
166144
setChatInput('')
167145
}
168146

169147
// Don't allow expanded view for tiny voice mode
170148
const showExpandedView = isExpanded && !(mode === 'voice' && size === 'tiny')
171149

172-
// Handle floating button click
173150
const handleFloatingButtonClick = () => {
174151
setIsExpanded(true)
175152
}
@@ -178,7 +155,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
178155
<>
179156
<div className={`fixed z-[50] ${positionClasses[position]}`}>
180157
{showExpandedView ? (
181-
// Check if we need to show consent form or the actual widget
182158
requireConsent && !hasConsent ? (
183159
<ConsentForm
184160
termsContent={termsContent}
@@ -189,7 +165,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
189165
radius={radius}
190166
/>
191167
) : (
192-
// Expanded Widget
193168
<div
194169
className={`${sizeClasses[size].expanded} ${radiusClasses[radius]} border flex flex-col overflow-hidden ${
195170
styles.theme === 'dark'
@@ -230,7 +205,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
230205
: {})
231206
}}
232207
>
233-
{/* Show transcript when: showTranscript is true OR in chat mode OR in hybrid mode but voice is not active */}
234208
{(showTranscript || mode === 'chat' || (mode === 'hybrid' && !vapi.voice.isCallActive)) ? (
235209
<>
236210
{vapi.conversation.length === 0 ? (
@@ -268,7 +242,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
268242
)}
269243
</>
270244
) : (
271-
/* Show center volume indicator when transcript is hidden and voice call is active */
272245
vapi.voice.isCallActive ? (
273246
<VolumeIndicator
274247
volumeLevel={vapi.voice.volumeLevel}
@@ -348,7 +321,6 @@ const VapiWidget: React.FC<VapiWidgetProps> = ({
348321
</div>
349322
)
350323
) : (
351-
// Floating Button - Always visible
352324
<FloatingButton
353325
isCallActive={vapi.voice.isCallActive}
354326
connectionStatus={vapi.voice.connectionStatus}

src/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
export { default as AnimatedStatusIcon } from './AnimatedStatusIcon'
22
export { default as VapiWidget } from './VapiWidget'
3+
34
export type { VapiWidgetProps } from './types'
45
export type { AnimatedStatusIconProps } from './AnimatedStatusIcon'

src/components/types.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
export interface VapiWidgetProps {
22
publicKey: string
33

4-
// Vapi Configuration - Generic support for all vapi.start() patterns
4+
// Vapi Configuration
55
vapiConfig: any // This gets passed directly to vapi.start()
66

77
// API Configuration
8-
apiUrl?: string // Optional custom API URL for chat
8+
apiUrl?: string
99

1010
// Layout & Position
1111
position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'
@@ -41,7 +41,7 @@ export interface VapiWidgetProps {
4141
// Transcript
4242
showTranscript?: boolean
4343

44-
// Legacy props (for backwards compatibility)
44+
// TODO: Remove this
4545
primaryColor?: string
4646

4747
// Event handlers

src/components/widget/WidgetHeader.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const WidgetHeader: React.FC<WidgetHeaderProps> = ({
1616
colors,
1717
styles
1818
}) => {
19-
// Determine the status message based on current state
19+
2020
const getStatusMessage = () => {
2121
if (connectionStatus === 'connecting') return 'Connecting...'
2222

@@ -26,14 +26,12 @@ const WidgetHeader: React.FC<WidgetHeaderProps> = ({
2626

2727
if (isTyping) return 'Assistant is typing...'
2828

29-
// If there's an active conversation, show appropriate status
3029
if (hasActiveConversation) {
3130
if (mode === 'chat') return 'Chat active'
3231
if (mode === 'hybrid') return 'Ready to assist'
3332
return 'Connected'
3433
}
3534

36-
// No conversation yet - show how to start
3735
if (mode === 'voice') return 'Click the microphone to start'
3836
if (mode === 'chat') return 'Type a message below'
3937
return 'Choose voice or text'

src/components/widget/conversation/Message.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,10 @@ import ReactMarkdown from 'react-markdown'
33
import { ConversationMessageProps, MarkdownMessageProps } from '../../types'
44
import { messageRadiusClasses } from '../../constants'
55

6-
// Markdown message renderer component
76
const MarkdownMessage: React.FC<MarkdownMessageProps> = ({ content, isLoading, role }) => (
87
<div className="markdown-content">
98
<ReactMarkdown
109
components={{
11-
// Style markdown elements to fit the chat bubble design
1210
p: ({children}) => <p className="mb-1 last:mb-0">{children}</p>,
1311
ul: ({children}) => <ul className="list-disc list-inside mb-1 last:mb-0">{children}</ul>,
1412
ol: ({children}) => <ol className="list-decimal list-inside mb-1 last:mb-0">{children}</ol>,

src/hooks/useVapiChat.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,6 @@ export const useVapiChat = ({
9090
try {
9191
setIsLoading(true)
9292

93-
// Add user message
9493
const userMessage: ChatMessage = {
9594
role: 'user',
9695
content: text.trim(),
@@ -103,15 +102,13 @@ export const useVapiChat = ({
103102
assistantMessageIndexRef.current = null
104103
setIsTyping(true)
105104

106-
// Start streaming
107105
const abort = await clientRef.current.streamChat(
108106
{
109107
input: text.trim(),
110108
assistantId,
111109
sessionId, // Use current sessionId if available
112110
stream: true
113111
},
114-
// On chunk callback
115112
(chunk) => {
116113
// Update sessionId if provided in response
117114
if (chunk.sessionId && chunk.sessionId !== sessionId) {
@@ -122,23 +119,19 @@ export const useVapiChat = ({
122119
if (content) {
123120
currentAssistantMessageRef.current += content
124121

125-
// Update the assistant message in real-time
126122
setMessages(prev => {
127123
const newMessages = [...prev]
128124

129125
// Check if we already have an assistant message index for this stream
130126
if (assistantMessageIndexRef.current !== null && assistantMessageIndexRef.current < newMessages.length) {
131-
// Update existing message by creating a new object
132127
const existingMessage = newMessages[assistantMessageIndexRef.current]
133128
if (existingMessage && existingMessage.role === 'assistant') {
134-
// Create a new message object to trigger React re-render
135129
newMessages[assistantMessageIndexRef.current] = {
136130
...existingMessage,
137131
content: currentAssistantMessageRef.current
138132
}
139133
}
140134
} else {
141-
// Create new assistant message and track its index
142135
assistantMessageIndexRef.current = newMessages.length
143136
newMessages.push({
144137
role: 'assistant',

0 commit comments

Comments
 (0)