Spaces:
Building
Building
Update flare-ui/src/app/components/chat/realtime-chat.component.ts
Browse files
flare-ui/src/app/components/chat/realtime-chat.component.ts
CHANGED
@@ -44,6 +44,8 @@ export class RealtimeChatComponent implements OnInit, OnDestroy, AfterViewChecke
|
|
44 |
messages: ConversationMessage[] = [];
|
45 |
error = '';
|
46 |
loading = false;
|
|
|
|
|
47 |
|
48 |
conversationStates: ConversationState[] = [
|
49 |
'idle', 'listening', 'processing_stt', 'processing_llm', 'processing_tts', 'playing_audio'
|
@@ -66,7 +68,7 @@ export class RealtimeChatComponent implements OnInit, OnDestroy, AfterViewChecke
|
|
66 |
this.projectName = data.projectName || null;
|
67 |
}
|
68 |
|
69 |
-
ngOnInit(): void {
|
70 |
console.log('🎤 RealtimeChat component initialized');
|
71 |
console.log('Session ID:', this.sessionId);
|
72 |
console.log('Project Name:', this.projectName);
|
@@ -103,25 +105,19 @@ ngOnInit(): void {
|
|
103 |
this.conversationManager.currentState$.pipe(
|
104 |
takeUntil(this.destroyed$)
|
105 |
).subscribe(state => {
|
106 |
-
console.log('📊
|
107 |
this.currentState = state;
|
108 |
|
109 |
-
//
|
110 |
-
|
111 |
-
|
112 |
-
|
113 |
-
// Eğer listening state'e geçtiyse ve konuşma aktifse visualization'ı başlat
|
114 |
-
if (state === 'listening' && this.isConversationActive && !this.animationId) {
|
115 |
-
console.log('🎤 Starting visualization for listening state');
|
116 |
-
this.startVisualization();
|
117 |
-
}
|
118 |
});
|
119 |
|
120 |
// Subscribe to transcription
|
121 |
this.conversationManager.transcription$.pipe(
|
122 |
takeUntil(this.destroyed$)
|
123 |
).subscribe(text => {
|
124 |
-
console.log('🎙️ Transcription update:', text);
|
125 |
this.currentTranscription = text;
|
126 |
});
|
127 |
|
@@ -182,8 +178,10 @@ ngOnInit(): void {
|
|
182 |
await this.conversationManager.startConversation(this.sessionId!);
|
183 |
this.isConversationActive = true;
|
184 |
|
185 |
-
// Visualization'ı başlat
|
|
|
186 |
this.startVisualization();
|
|
|
187 |
|
188 |
this.snackBar.open('Konuşma başlatıldı', 'Close', {
|
189 |
duration: 2000
|
@@ -203,6 +201,7 @@ ngOnInit(): void {
|
|
203 |
private stopConversation(): void {
|
204 |
this.conversationManager.stopConversation();
|
205 |
this.isConversationActive = false;
|
|
|
206 |
this.stopVisualization();
|
207 |
|
208 |
this.snackBar.open('Konuşma sonlandırıldı', 'Close', {
|
@@ -319,6 +318,11 @@ ngOnInit(): void {
|
|
319 |
return;
|
320 |
}
|
321 |
|
|
|
|
|
|
|
|
|
|
|
322 |
const canvas = this.audioVisualizer.nativeElement;
|
323 |
const ctx = canvas.getContext('2d');
|
324 |
if (!ctx) {
|
@@ -330,12 +334,13 @@ ngOnInit(): void {
|
|
330 |
canvas.width = canvas.offsetWidth;
|
331 |
canvas.height = canvas.offsetHeight;
|
332 |
|
333 |
-
|
334 |
|
335 |
// Subscribe to audio service volume level
|
336 |
this.subscriptions.add(
|
337 |
this.audioService.volumeLevel$.subscribe(volume => {
|
338 |
-
|
|
|
339 |
this.drawVolumeVisualization(ctx, canvas, volume);
|
340 |
}
|
341 |
})
|
@@ -343,7 +348,9 @@ ngOnInit(): void {
|
|
343 |
|
344 |
// Animation loop
|
345 |
const animate = () => {
|
346 |
-
|
|
|
|
|
347 |
this.clearVisualization();
|
348 |
return;
|
349 |
}
|
@@ -352,16 +359,13 @@ ngOnInit(): void {
|
|
352 |
ctx.fillStyle = 'rgba(26, 26, 26, 0.1)';
|
353 |
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
354 |
|
355 |
-
//
|
356 |
-
|
357 |
-
|
358 |
-
|
359 |
-
|
360 |
-
|
361 |
-
|
362 |
-
ctx.lineTo(canvas.width, canvas.height / 2);
|
363 |
-
ctx.stroke();
|
364 |
-
}
|
365 |
|
366 |
this.animationId = requestAnimationFrame(animate);
|
367 |
};
|
|
|
44 |
messages: ConversationMessage[] = [];
|
45 |
error = '';
|
46 |
loading = false;
|
47 |
+
|
48 |
+
isVisualizationActive = false;
|
49 |
|
50 |
conversationStates: ConversationState[] = [
|
51 |
'idle', 'listening', 'processing_stt', 'processing_llm', 'processing_tts', 'playing_audio'
|
|
|
68 |
this.projectName = data.projectName || null;
|
69 |
}
|
70 |
|
71 |
+
ngOnInit(): void {
|
72 |
console.log('🎤 RealtimeChat component initialized');
|
73 |
console.log('Session ID:', this.sessionId);
|
74 |
console.log('Project Name:', this.projectName);
|
|
|
105 |
this.conversationManager.currentState$.pipe(
|
106 |
takeUntil(this.destroyed$)
|
107 |
).subscribe(state => {
|
108 |
+
console.log('📊 UI received conversation state:', state);
|
109 |
this.currentState = state;
|
110 |
|
111 |
+
// State ne olursa olsun, konuşma aktifse recording true
|
112 |
+
this.isRecording = this.isConversationActive && state !== 'error';
|
113 |
+
console.log('🎤 Recording state updated:', this.isRecording, 'State:', state);
|
|
|
|
|
|
|
|
|
|
|
|
|
114 |
});
|
115 |
|
116 |
// Subscribe to transcription
|
117 |
this.conversationManager.transcription$.pipe(
|
118 |
takeUntil(this.destroyed$)
|
119 |
).subscribe(text => {
|
120 |
+
console.log('🎙️ Transcription update:', text ? `"${text}"` : '(empty)');
|
121 |
this.currentTranscription = text;
|
122 |
});
|
123 |
|
|
|
178 |
await this.conversationManager.startConversation(this.sessionId!);
|
179 |
this.isConversationActive = true;
|
180 |
|
181 |
+
// Visualization'ı başlat ve aktif olarak işaretle
|
182 |
+
this.isVisualizationActive = true;
|
183 |
this.startVisualization();
|
184 |
+
console.log('✅ Conversation and visualization started');
|
185 |
|
186 |
this.snackBar.open('Konuşma başlatıldı', 'Close', {
|
187 |
duration: 2000
|
|
|
201 |
private stopConversation(): void {
|
202 |
this.conversationManager.stopConversation();
|
203 |
this.isConversationActive = false;
|
204 |
+
this.isVisualizationActive = false;
|
205 |
this.stopVisualization();
|
206 |
|
207 |
this.snackBar.open('Konuşma sonlandırıldı', 'Close', {
|
|
|
318 |
return;
|
319 |
}
|
320 |
|
321 |
+
if (this.animationId) {
|
322 |
+
console.log('🎨 Visualization already running');
|
323 |
+
return;
|
324 |
+
}
|
325 |
+
|
326 |
const canvas = this.audioVisualizer.nativeElement;
|
327 |
const ctx = canvas.getContext('2d');
|
328 |
if (!ctx) {
|
|
|
334 |
canvas.width = canvas.offsetWidth;
|
335 |
canvas.height = canvas.offsetHeight;
|
336 |
|
337 |
+
console.log('🎨 Starting continuous visualization');
|
338 |
|
339 |
// Subscribe to audio service volume level
|
340 |
this.subscriptions.add(
|
341 |
this.audioService.volumeLevel$.subscribe(volume => {
|
342 |
+
// Konuşma aktif olduğu sürece her zaman visualize et
|
343 |
+
if (this.isVisualizationActive) {
|
344 |
this.drawVolumeVisualization(ctx, canvas, volume);
|
345 |
}
|
346 |
})
|
|
|
348 |
|
349 |
// Animation loop
|
350 |
const animate = () => {
|
351 |
+
// Visualization aktif olduğu sürece devam et
|
352 |
+
if (!this.isVisualizationActive) {
|
353 |
+
console.log('🎨 Stopping animation - visualization inactive');
|
354 |
this.clearVisualization();
|
355 |
return;
|
356 |
}
|
|
|
359 |
ctx.fillStyle = 'rgba(26, 26, 26, 0.1)';
|
360 |
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
361 |
|
362 |
+
// Always draw center line
|
363 |
+
ctx.strokeStyle = 'rgba(76, 175, 80, 0.3)';
|
364 |
+
ctx.lineWidth = 1;
|
365 |
+
ctx.beginPath();
|
366 |
+
ctx.moveTo(0, canvas.height / 2);
|
367 |
+
ctx.lineTo(canvas.width, canvas.height / 2);
|
368 |
+
ctx.stroke();
|
|
|
|
|
|
|
369 |
|
370 |
this.animationId = requestAnimationFrame(animate);
|
371 |
};
|