@@ -18,7 +18,10 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
1818 const [ timerId , setTimerId ] = useState < NodeJS . Timeout | null > ( null ) ;
1919 const [ milliseconds , setMilliseconds ] = useState < number > ( 0 ) ;
2020 const millisecondTimerRef = useRef < NodeJS . Timeout | null > ( null ) ;
21- const [ audioPermissionGranted , setAudioPermissionGranted ] = useState < boolean > ( false ) ;
21+ const [ audioPermissionGranted , setAudioPermissionGranted ] = useState < boolean > ( ( ) => {
22+ // Initialize with cached permission status
23+ return localStorage . getItem ( 'microphone_permission_granted' ) === 'true' ;
24+ } ) ;
2225 const [ audioLevel , setAudioLevel ] = useState < number [ ] > ( Array ( 30 ) . fill ( 0 ) ) ;
2326 const animationFrameRef = useRef < number | null > ( null ) ;
2427 const audioContextRef = useRef < AudioContext | null > ( null ) ;
@@ -132,23 +135,28 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
132135 useEffect ( ( ) => {
133136 const initRecording = async ( ) => {
134137 try {
135- // First check/request permission
136- const hasPermission = await checkMicrophonePermission ( ) ;
137- if ( ! hasPermission ) {
138- const granted = await requestMicrophonePermission ( ) ;
139- if ( ! granted ) {
140- setAudioPermissionGranted ( false ) ;
141- console . error ( 'Microphone permission denied' ) ;
142- return ;
138+ // If we already have cached permission, skip permission check
139+ const cachedPermission = localStorage . getItem ( 'microphone_permission_granted' ) === 'true' ;
140+
141+ if ( ! cachedPermission ) {
142+ // First check/request permission
143+ const hasPermission = await checkMicrophonePermission ( ) ;
144+ if ( ! hasPermission ) {
145+ const granted = await requestMicrophonePermission ( ) ;
146+ if ( ! granted ) {
147+ setAudioPermissionGranted ( false ) ;
148+ console . error ( 'Microphone permission denied' ) ;
149+ return ;
150+ }
143151 }
152+ // Permission granted, update state
153+ setAudioPermissionGranted ( true ) ;
144154 }
145155
146156 const stream = await startRecording ( ) ;
147157 if ( stream ) {
148158 setupAudioAnalyser ( stream ) ;
149- setAudioPermissionGranted ( true ) ;
150159 } else {
151- setAudioPermissionGranted ( false ) ;
152160 console . error ( 'Failed to start recording' ) ;
153161 return ;
154162 }
@@ -167,6 +175,9 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
167175 millisecondTimerRef . current = msTimer ;
168176 } catch ( error ) {
169177 console . error ( "Failed to start recording:" , error ) ;
178+ // Clear cached permission on error
179+ localStorage . removeItem ( 'microphone_permission_granted' ) ;
180+ setAudioPermissionGranted ( false ) ;
170181 }
171182 } ;
172183
@@ -268,36 +279,16 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
268279 } , [ recordingBlob , onComplete , recordingTime ] ) ;
269280
270281 const handleDelete = useCallback ( ( ) => {
271- setLastRecordingBlob ( null ) ;
272- setRecordingTime ( 0 ) ;
273- setMilliseconds ( 0 ) ;
274-
275- const initNewRecording = async ( ) => {
276- try {
277- const stream = await startRecording ( ) ;
278- if ( stream ) {
279- setupAudioAnalyser ( stream ) ;
280- }
281- setIsRecording ( true ) ;
282-
283- // Restart timer
284- const timer = setInterval ( ( ) => {
285- setRecordingTime ( prev => prev + 1 ) ;
286- } , 1000 ) ;
287- setTimerId ( timer ) ;
282+ // Stop current recording
283+ stopRecording ( ) ;
288284
289- // Restart milliseconds timer
290- const msTimer = setInterval ( ( ) => {
291- setMilliseconds ( prev => ( prev + 1 ) % 100 ) ;
292- } , 10 ) ;
293- millisecondTimerRef . current = msTimer ;
294- } catch ( error ) {
295- console . error ( "Failed to restart recording:" , error ) ;
296- }
297- } ;
285+ // Clean up timers
286+ if ( timerId ) clearInterval ( timerId ) ;
287+ if ( millisecondTimerRef . current ) clearInterval ( millisecondTimerRef . current ) ;
298288
299- initNewRecording ( ) ;
300- } , [ startRecording , setupAudioAnalyser ] ) ;
289+ // Close the dialog
290+ RootStore . Get ( DialogStandaloneStore ) . close ( ) ;
291+ } , [ stopRecording , timerId ] ) ;
301292
302293 // Format time display as MM:SS.XX
303294 const formattedTime = useMemo ( ( ) => {
@@ -310,7 +301,7 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
310301 const { t } = useTranslation ( ) ;
311302
312303 return (
313- < div className = "relative flex flex-col items-center overflow-hidden" >
304+ < div className = "relative flex flex-col items-center overflow-hidden w-full h-[450px] " >
314305 { ! audioPermissionGranted ? (
315306 // Permission Request UI - Clean and Professional
316307 < div className = "flex flex-col items-center justify-center w-full h-full p-8 rounded-lg" >
@@ -345,15 +336,13 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
345336 </ div >
346337 ) : (
347338 // Recording UI - Original design when permission is granted
348- < div className = "flex flex-col items-center justify-center w-full h-full p-4 bg-neutral-900 rounded-lg" >
349- < div className = "w-full" >
350- < div className = "flex items-center" >
351- < span className = "text-white font-bold" > REC</ span >
352- < span className = "ml-2 w-2 h-2 bg-red-500 rounded-full animate-pulse" > </ span >
353- </ div >
339+ < div className = "flex flex-col items-center w-full h-full p-4 bg-neutral-900 rounded-lg" >
340+ < div className = "w-full h-8 flex items-center" >
341+ < span className = "text-white font-bold" > REC</ span >
342+ < span className = "ml-2 w-2 h-2 bg-red-500 rounded-full animate-pulse" > </ span >
354343 </ div >
355344
356- < div className = "w-full flex-1 flex flex-col items-center justify-center my-4 " >
345+ < div className = "w-full flex-1 flex flex-col items-center justify-center py-4 min-h-[200px] " >
357346 < div className = "my-4 w-full" >
358347 < div className = "w-full h-[40px] flex items-center justify-center rounded" >
359348 < div className = "w-full h-full flex items-end justify-center space-x-1 px-2" >
@@ -378,7 +367,7 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
378367 </ div >
379368 </ div >
380369
381- < div className = "flex justify-center mt-4 w-full" >
370+ < div className = "flex justify-center mt-4 w-full h-16 " >
382371 { isRecording ? (
383372 < button
384373 className = "w-16 h-16 rounded-full bg-green-500 flex items-center justify-center focus:outline-none active:transform active:scale-95 transition-transform"
@@ -387,7 +376,7 @@ export const MyAudioRecorder = ({ onComplete }: MyAudioRecorderProps) => {
387376 < div className = "w-6 h-6 bg-white rounded" > </ div >
388377 </ button >
389378 ) : (
390- < div className = "flex gap-5" >
379+ < div className = "flex gap-5 items-center justify-center h-full " >
391380 < button
392381 className = "w-16 h-16 rounded-full bg-neutral-800 flex items-center justify-center focus:outline-none active:transform active:scale-95 transition-transform"
393382 onClick = { handleDelete }
0 commit comments