flare / flare-ui /src /app /components /chat /chat.component.ts
ciyidogan's picture
Update flare-ui/src/app/components/chat/chat.component.ts
6ad271f verified
raw
history blame
4.92 kB
import { Component, OnInit, OnDestroy, ViewChild, ElementRef, AfterViewChecked } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormBuilder, ReactiveFormsModule, Validators, FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material/input';
import { MatCardModule } from '@angular/material/card';
import { MatSelectModule } from '@angular/material/select';
import { MatDividerModule } from '@angular/material/divider';
import { MatTooltipModule } from '@angular/material/tooltip';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { Subscription } from 'rxjs';
import { ApiService } from '../../services/api.service';
interface ChatMessage {
author: 'user' | 'assistant';
text: string;
timestamp?: Date;
}
@Component({
selector: 'app-chat',
standalone: true,
imports: [
CommonModule,
FormsModule,
ReactiveFormsModule,
MatButtonModule,
MatIconModule,
MatFormFieldModule,
MatInputModule,
MatCardModule,
MatSelectModule,
MatDividerModule,
MatTooltipModule,
MatProgressSpinnerModule
],
templateUrl: './chat.component.html',
styleUrls: ['./chat.component.scss']
})
export class ChatComponent implements OnInit, OnDestroy, AfterViewChecked {
@ViewChild('scrollMe') private myScrollContainer!: ElementRef;
projects: string[] = [];
selectedProject: string | null = null; // Düzeltildi: ! kaldırıldı, null değer atandı
sessionId: string | null = null;
messages: ChatMessage[] = [];
input = this.fb.control('', Validators.required);
loading = false;
error = '';
private subs = new Subscription();
private shouldScroll = false;
constructor(
private fb: FormBuilder,
private api: ApiService
) {}
ngOnInit(): void {
this.loadProjects();
}
ngAfterViewChecked() {
if (this.shouldScroll) {
this.scrollToBottom();
this.shouldScroll = false;
}
}
ngOnDestroy(): void {
this.subs.unsubscribe();
}
loadProjects(): void {
this.loading = true;
const sub = this.api.getChatProjects().subscribe({
next: projects => {
this.projects = projects;
this.loading = false;
if (projects.length === 0) {
this.error = 'No enabled projects found. Please enable a project with published version.';
}
},
error: (err) => {
this.error = 'Failed to load projects';
this.loading = false;
console.error('Load projects error:', err);
}
});
this.subs.add(sub);
}
startChat(): void {
if (!this.selectedProject) return;
this.loading = true;
this.error = '';
const sub = this.api.startChat(this.selectedProject).subscribe({
next: res => {
this.sessionId = res.session_id;
this.messages = [{
author: 'assistant',
text: res.answer,
timestamp: new Date()
}];
this.loading = false;
this.shouldScroll = true;
},
error: (err) => {
this.error = err.error?.detail || 'Failed to start session';
this.loading = false;
console.error('Start chat error:', err);
}
});
this.subs.add(sub);
}
send(): void {
if (!this.sessionId || this.input.invalid) return;
const text = this.input.value!.trim();
if (!text) return;
// Add user message
this.messages.push({
author: 'user',
text,
timestamp: new Date()
});
this.input.reset();
this.loading = true;
this.shouldScroll = true;
// Send to backend
const sub = this.api.chat(this.sessionId, text).subscribe({
next: res => {
this.messages.push({
author: 'assistant',
text: res.answer,
timestamp: new Date()
});
this.loading = false;
this.shouldScroll = true;
},
error: (err) => {
this.messages.push({
author: 'assistant',
text: '⚠️ ' + (err.error?.detail || 'Failed to send message. Please try again.'),
timestamp: new Date()
});
this.loading = false;
this.shouldScroll = true;
console.error('Chat error:', err);
}
});
this.subs.add(sub);
}
endSession(): void {
this.sessionId = null;
this.messages = [];
this.selectedProject = null;
this.input.reset();
this.error = '';
}
private scrollToBottom(): void {
try {
if (this.myScrollContainer) {
this.myScrollContainer.nativeElement.scrollTop =
this.myScrollContainer.nativeElement.scrollHeight;
}
} catch(err) {
console.error('Scroll error:', err);
}
}
}