Spaces:
Building
Building
Update flare-ui/src/app/components/chat/chat.component.ts
Browse files
flare-ui/src/app/components/chat/chat.component.ts
CHANGED
@@ -11,10 +11,13 @@ import { MatDividerModule } from '@angular/material/divider';
|
|
11 |
import { MatTooltipModule } from '@angular/material/tooltip';
|
12 |
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
13 |
import { MatCheckboxModule } from '@angular/material/checkbox';
|
|
|
14 |
import { Subscription } from 'rxjs';
|
15 |
|
16 |
import { ApiService } from '../../services/api.service';
|
17 |
import { EnvironmentService } from '../../services/environment.service';
|
|
|
|
|
18 |
|
19 |
interface ChatMessage {
|
20 |
author: 'user' | 'assistant';
|
@@ -39,7 +42,8 @@ interface ChatMessage {
|
|
39 |
MatDividerModule,
|
40 |
MatTooltipModule,
|
41 |
MatProgressSpinnerModule,
|
42 |
-
MatCheckboxModule
|
|
|
43 |
],
|
44 |
templateUrl: './chat.component.html',
|
45 |
styleUrls: ['./chat.component.scss']
|
@@ -64,6 +68,7 @@ export class ChatComponent implements OnInit, OnDestroy, AfterViewChecked {
|
|
64 |
useSTT = false;
|
65 |
sttAvailable = false;
|
66 |
isListening = false;
|
|
|
67 |
|
68 |
// Audio visualization
|
69 |
audioContext?: AudioContext;
|
@@ -76,7 +81,9 @@ export class ChatComponent implements OnInit, OnDestroy, AfterViewChecked {
|
|
76 |
constructor(
|
77 |
private fb: FormBuilder,
|
78 |
private api: ApiService,
|
79 |
-
private environmentService: EnvironmentService
|
|
|
|
|
80 |
) {}
|
81 |
|
82 |
ngOnInit(): void {
|
@@ -86,6 +93,9 @@ export class ChatComponent implements OnInit, OnDestroy, AfterViewChecked {
|
|
86 |
|
87 |
// Initialize Audio Context
|
88 |
this.audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
|
|
|
|
|
|
|
89 |
}
|
90 |
|
91 |
ngAfterViewChecked() {
|
@@ -105,6 +115,94 @@ export class ChatComponent implements OnInit, OnDestroy, AfterViewChecked {
|
|
105 |
}
|
106 |
}
|
107 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
108 |
loadProjects(): void {
|
109 |
this.loading = true;
|
110 |
const sub = this.api.getChatProjects().subscribe({
|
|
|
11 |
import { MatTooltipModule } from '@angular/material/tooltip';
|
12 |
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
|
13 |
import { MatCheckboxModule } from '@angular/material/checkbox';
|
14 |
+
import { MatDialog } from '@angular/material/dialog';
|
15 |
import { Subscription } from 'rxjs';
|
16 |
|
17 |
import { ApiService } from '../../services/api.service';
|
18 |
import { EnvironmentService } from '../../services/environment.service';
|
19 |
+
import { RealtimeChatComponent } from './realtime-chat.component';
|
20 |
+
import { Router } from '@angular/router';
|
21 |
|
22 |
interface ChatMessage {
|
23 |
author: 'user' | 'assistant';
|
|
|
42 |
MatDividerModule,
|
43 |
MatTooltipModule,
|
44 |
MatProgressSpinnerModule,
|
45 |
+
MatCheckboxModule,
|
46 |
+
RealtimeChatComponent
|
47 |
],
|
48 |
templateUrl: './chat.component.html',
|
49 |
styleUrls: ['./chat.component.scss']
|
|
|
68 |
useSTT = false;
|
69 |
sttAvailable = false;
|
70 |
isListening = false;
|
71 |
+
sttAvailable = false;
|
72 |
|
73 |
// Audio visualization
|
74 |
audioContext?: AudioContext;
|
|
|
81 |
constructor(
|
82 |
private fb: FormBuilder,
|
83 |
private api: ApiService,
|
84 |
+
private environmentService: EnvironmentService,
|
85 |
+
private dialog: MatDialog,
|
86 |
+
private router: Router
|
87 |
) {}
|
88 |
|
89 |
ngOnInit(): void {
|
|
|
93 |
|
94 |
// Initialize Audio Context
|
95 |
this.audioContext = new (window.AudioContext || (window as any).webkitAudioContext)();
|
96 |
+
|
97 |
+
// STT availability kontrolü
|
98 |
+
this.checkSTTAvailability();
|
99 |
}
|
100 |
|
101 |
ngAfterViewChecked() {
|
|
|
115 |
}
|
116 |
}
|
117 |
|
118 |
+
private checkSTTAvailability(): void {
|
119 |
+
this.api.getEnvironment().subscribe({
|
120 |
+
next: (env) => {
|
121 |
+
this.sttAvailable = env.stt_engine !== 'no_stt';
|
122 |
+
if (!this.sttAvailable) {
|
123 |
+
this.useSTT = false;
|
124 |
+
}
|
125 |
+
},
|
126 |
+
error: (err) => {
|
127 |
+
console.error('Failed to check STT availability:', err);
|
128 |
+
this.sttAvailable = false;
|
129 |
+
}
|
130 |
+
});
|
131 |
+
}
|
132 |
+
|
133 |
+
startRealtimeChat(): void {
|
134 |
+
if (!this.selectedProject) {
|
135 |
+
this.error = 'Please select a project first';
|
136 |
+
return;
|
137 |
+
}
|
138 |
+
|
139 |
+
if (!this.sttAvailable) {
|
140 |
+
this.error = 'STT is not configured. Please configure it in Environment settings.';
|
141 |
+
return;
|
142 |
+
}
|
143 |
+
|
144 |
+
this.loading = true;
|
145 |
+
this.error = '';
|
146 |
+
|
147 |
+
// Start a new session for realtime chat
|
148 |
+
const sub = this.api.startChat(this.selectedProject).subscribe({
|
149 |
+
next: res => {
|
150 |
+
// Store session ID for realtime component
|
151 |
+
localStorage.setItem('current_session_id', res.session_id);
|
152 |
+
localStorage.setItem('current_project', this.selectedProject);
|
153 |
+
|
154 |
+
// Open realtime chat dialog
|
155 |
+
this.openRealtimeDialog(res.session_id);
|
156 |
+
|
157 |
+
this.loading = false;
|
158 |
+
},
|
159 |
+
error: (err) => {
|
160 |
+
this.error = err.error?.detail || 'Failed to start realtime session';
|
161 |
+
this.loading = false;
|
162 |
+
console.error('Start realtime chat error:', err);
|
163 |
+
}
|
164 |
+
});
|
165 |
+
|
166 |
+
this.subs.add(sub);
|
167 |
+
}
|
168 |
+
|
169 |
+
private openRealtimeDialog(sessionId: string): void {
|
170 |
+
const dialogRef = this.dialog.open(RealtimeChatComponent, {
|
171 |
+
width: '90%',
|
172 |
+
maxWidth: '900px',
|
173 |
+
height: '85vh',
|
174 |
+
maxHeight: '800px',
|
175 |
+
disableClose: false,
|
176 |
+
panelClass: 'realtime-chat-dialog',
|
177 |
+
data: {
|
178 |
+
sessionId: sessionId,
|
179 |
+
projectName: this.selectedProject
|
180 |
+
}
|
181 |
+
});
|
182 |
+
|
183 |
+
dialogRef.afterClosed().subscribe(result => {
|
184 |
+
// Clean up session data
|
185 |
+
localStorage.removeItem('current_session_id');
|
186 |
+
localStorage.removeItem('current_project');
|
187 |
+
|
188 |
+
// If session was active, we might want to end it
|
189 |
+
if (result === 'session_active') {
|
190 |
+
// Optionally end the session on backend
|
191 |
+
this.api.endSession(sessionId).subscribe({
|
192 |
+
next: () => console.log('Session ended'),
|
193 |
+
error: (err) => console.error('Failed to end session:', err)
|
194 |
+
});
|
195 |
+
}
|
196 |
+
});
|
197 |
+
}
|
198 |
+
|
199 |
+
// Alternatif: Route navigasyonu kullanmak isterseniz
|
200 |
+
private navigateToRealtimeChat(sessionId: string): void {
|
201 |
+
this.router.navigate(['/realtime-chat', sessionId], {
|
202 |
+
queryParams: { project: this.selectedProject }
|
203 |
+
});
|
204 |
+
}
|
205 |
+
|
206 |
loadProjects(): void {
|
207 |
this.loading = true;
|
208 |
const sub = this.api.getChatProjects().subscribe({
|