1- import { Mic , MicOff , Loader2 } from 'lucide-react'
1+ import { Mic , Square , Loader2 } from 'lucide-react'
22import { RecordingContextType } from '../../contexts/RecordingContext'
33
44interface SimplifiedControlsProps {
@@ -18,73 +18,82 @@ const getStepText = (step: string): string => {
1818 }
1919}
2020
21- const getButtonColor = ( step : string , isRecording : boolean ) : string => {
22- if ( step === 'error' ) return 'bg-red-600 hover:bg-red-700'
23- if ( isRecording ) return 'bg-red-600 hover:bg-red-700'
24- if ( step === 'idle' ) return 'bg-blue-600 hover:bg-blue-700'
25- return 'bg-yellow-600 hover:bg-yellow-700'
26- }
27-
2821const isProcessing = ( step : string ) : boolean => {
2922 return [ 'mic' , 'websocket' , 'audio-start' , 'streaming' , 'stopping' ] . includes ( step )
3023}
3124
3225export default function SimplifiedControls ( { recording } : SimplifiedControlsProps ) {
33- const startButtonDisabled = ! recording . canAccessMicrophone || isProcessing ( recording . currentStep ) || recording . isRecording
34-
26+ const processing = isProcessing ( recording . currentStep )
27+ const canStart = recording . canAccessMicrophone && ! processing && ! recording . isRecording
28+
29+ const handleClick = ( ) => {
30+ if ( recording . isRecording ) {
31+ recording . stopRecording ( )
32+ } else if ( canStart ) {
33+ recording . startRecording ( )
34+ }
35+ }
36+
37+ // Button appearance based on state
38+ const getButtonClasses = ( ) : string => {
39+ if ( recording . isRecording ) return 'bg-red-600 hover:bg-red-700'
40+ if ( processing ) return 'bg-yellow-600'
41+ if ( recording . currentStep === 'error' ) return 'bg-red-600 hover:bg-red-700'
42+ return 'bg-blue-600 hover:bg-blue-700'
43+ }
44+
45+ const isDisabled = recording . isRecording ? false : ( processing || ! canStart )
46+
3547 return (
3648 < div className = "bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-8 mb-6" >
3749 < div className = "text-center" >
38- { /* Control Buttons */ }
39- < div className = "mb-6 flex justify-center space-x-4" >
40- { /* START Button */ }
41- < button
42- onClick = { recording . startRecording }
43- disabled = { startButtonDisabled }
44- className = { `w-24 h-24 ${ recording . isRecording || isProcessing ( recording . currentStep ) ? 'bg-gray-400' : getButtonColor ( recording . currentStep , recording . isRecording ) } text-white rounded-full flex items-center justify-center transition-all duration-200 shadow-lg disabled:opacity-50 disabled:cursor-not-allowed transform hover:scale-105 active:scale-95` }
45- >
46- { isProcessing ( recording . currentStep ) ? (
47- < Loader2 className = "h-10 w-10 animate-spin" />
48- ) : (
49- < Mic className = "h-10 w-10" />
50+ { /* Single Toggle Button */ }
51+ < div className = "mb-6 flex justify-center" >
52+ < div className = "relative" >
53+ { /* Pulsing ring when recording */ }
54+ { recording . isRecording && (
55+ < span className = "absolute inset-0 rounded-full bg-red-400 opacity-30 animate-ping" />
5056 ) }
51- </ button >
52-
53- { /* STOP Button - only show when recording */ }
54- { recording . isRecording && (
5557 < button
56- onClick = { recording . stopRecording }
57- className = "w-24 h-24 bg-red-600 hover:bg-red-700 text-white rounded-full flex items-center justify-center transition-all duration-200 shadow-lg transform hover:scale-105 active:scale-95"
58+ onClick = { handleClick }
59+ disabled = { isDisabled }
60+ className = { `relative w-24 h-24 ${ getButtonClasses ( ) } text-white rounded-full flex items-center justify-center transition-all duration-200 shadow-lg disabled:opacity-50 disabled:cursor-not-allowed transform hover:scale-105 active:scale-95` }
5861 >
59- < MicOff className = "h-10 w-10" />
62+ { recording . isRecording ? (
63+ < Square className = "h-10 w-10 fill-current" />
64+ ) : processing ? (
65+ < Loader2 className = "h-10 w-10 animate-spin" />
66+ ) : (
67+ < Mic className = "h-10 w-10" />
68+ ) }
6069 </ button >
61- ) }
70+ </ div >
6271 </ div >
63-
72+
6473 { /* Status Text */ }
6574 < div className = "space-y-2" >
6675 < h2 className = "text-xl font-semibold text-gray-900 dark:text-gray-100" >
6776 { recording . isRecording ? 'Recording in Progress' : getStepText ( recording . currentStep ) }
6877 </ h2 >
69-
78+
7079 { /* Recording Duration */ }
7180 { recording . isRecording && (
72- < p className = "text-3xl font-mono text-blue -600 dark:text-blue -400" >
81+ < p className = "text-3xl font-mono text-red -600 dark:text-red -400" >
7382 { recording . formatDuration ( recording . recordingDuration ) }
7483 </ p >
7584 ) }
76-
85+
7786 { /* Action Text */ }
7887 < p className = "text-sm text-gray-600 dark:text-gray-400" >
79- { recording . isRecording
80- ? 'Click the red STOP button to end recording'
81- : recording . currentStep === 'idle'
82- ? 'Click the blue START button to begin recording'
88+ { recording . isRecording
89+ ? 'Click to stop recording'
90+ : recording . currentStep === 'idle'
91+ ? 'Click to start recording'
8392 : recording . currentStep === 'error'
84- ? 'Click START to try again'
93+ ? 'Click to try again'
8594 : 'Please wait while setting up...' }
8695 </ p >
87-
96+
8897 { /* Error Message */ }
8998 { recording . error && (
9099 < div className = "mt-4 p-3 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg" >
@@ -93,7 +102,7 @@ export default function SimplifiedControls({ recording }: SimplifiedControlsProp
93102 </ p >
94103 </ div >
95104 ) }
96-
105+
97106 { /* Security Warning */ }
98107 { ! recording . canAccessMicrophone && (
99108 < div className = "mt-4 p-3 bg-orange-50 dark:bg-orange-900/20 border border-orange-200 dark:border-orange-800 rounded-lg" >
@@ -106,4 +115,4 @@ export default function SimplifiedControls({ recording }: SimplifiedControlsProp
106115 </ div >
107116 </ div >
108117 )
109- }
118+ }
0 commit comments