diff --git a/angular.json b/angular.json
index 1930f4b..9fbfd88 100644
--- a/angular.json
+++ b/angular.json
@@ -111,5 +111,8 @@
}
}
}
+ },
+ "cli": {
+ "analytics": false
}
}
\ No newline at end of file
diff --git a/src/app/chat/chat.component.html b/src/app/chat/chat.component.html
index 6f9e8a1..c44d7e9 100644
--- a/src/app/chat/chat.component.html
+++ b/src/app/chat/chat.component.html
@@ -6,7 +6,7 @@
CIT Chatbot
-
+
@@ -45,10 +45,13 @@
CIT Chatbot
(keydown)="onKeyDown($event)"
[placeholder]="placeholderText"
rows="1">
-
\ No newline at end of file
diff --git a/src/app/chat/chat.component.scss b/src/app/chat/chat.component.scss
index 8380b12..d745164 100644
--- a/src/app/chat/chat.component.scss
+++ b/src/app/chat/chat.component.scss
@@ -110,6 +110,12 @@ $logo-size: 40px;
&:hover {
background-color: $primary-color;
}
+
+ &.disabled {
+ background-color: $border-color;
+ color: #aaa;
+ cursor: not-allowed;
+ }
svg {
fill: white;
diff --git a/src/app/chat/chat.component.ts b/src/app/chat/chat.component.ts
index 0c031fd..8be62cb 100644
--- a/src/app/chat/chat.component.ts
+++ b/src/app/chat/chat.component.ts
@@ -21,7 +21,8 @@ export const MESSAGES = {
If you'd like program-specific advice, please select your study program from the dropdown menu at the top, and I'll provide you with the most relevant information.
`,
errorMessage: `Sorry, but I am currently unable to answer your questions. Please try again at a later time.`,
- placeholder: `Type your message here...`
+ placeholder: `Type your message here...`,
+ dropdownLabel: `Select Study Program:`
},
de: {
welcomeMessage: `
@@ -32,7 +33,8 @@ export const MESSAGES = {
Wenn Sie studiengangspezifische Ratschläge benötigen, wählen Sie bitte Ihr Studienprogramm aus dem Dropdown-Menü oben, und ich werde Ihnen die relevantesten Informationen bereitstellen.
`,
errorMessage: `Entschuldigung, aber ich kann Ihre Fragen derzeit nicht beantworten. Bitte versuchen Sie es später erneut.`,
- placeholder: `Geben Sie hier Ihre Nachricht ein...`
+ placeholder: `Geben Sie hier Ihre Nachricht ein...`,
+ dropdownLabel: `Studiengang auswählen:`
}
};
@@ -54,6 +56,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
placeholderText: string = '';
welcomeMessage: string = '';
errorMessage: string = '';
+ dropdownLabel: string = '';
// FormControl for the study program dropdown
studyProgramControl = new FormControl('');
@@ -61,6 +64,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
language: 'en' | 'de' = 'en'; // Default language is English
private needScrollToBottom: boolean = false;
+ disableSending: boolean = false;
constructor(private chatbotService: ChatbotService, private route: ActivatedRoute) { }
@@ -84,6 +88,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
this.welcomeMessage = MESSAGES[this.language].welcomeMessage;
this.errorMessage = MESSAGES[this.language].errorMessage;
this.placeholderText = MESSAGES[this.language].placeholder;
+ this.dropdownLabel = MESSAGES[this.language].dropdownLabel;
}
onKeyDown(event: KeyboardEvent): void {
@@ -92,7 +97,8 @@ export class ChatComponent implements OnInit, AfterViewChecked {
!event.shiftKey &&
!event.ctrlKey &&
!event.altKey &&
- !event.metaKey
+ !event.metaKey &&
+ !this.disableSending
) {
event.preventDefault(); // Prevents the default action of adding a newline
this.sendMessage();
@@ -102,6 +108,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
sendMessage() {
if (this.userMessage.trim()) {
// Add the user's message to the messages array
+ this.disableSending = true;
this.messages.push({ message: this.userMessage, type: 'user' });
this.userMessage = '';
this.resetTextAreaHeight();
@@ -113,9 +120,10 @@ export class ChatComponent implements OnInit, AfterViewChecked {
const loadingMessage: ChatMessage = { message: '', type: 'loading' };
this.messages.push(loadingMessage);
this.needScrollToBottom = true;
-
- // Prepare the messages to send to the bot, excluding the loading message
- const messagesToSend = this.messages.filter(msg => msg.type !== 'loading');
+
+ const nonLoadingMessages = this.messages.filter(msg => msg.type !== 'loading');
+ // Keep only the last 5 messages, if there are 5 or more
+ const messagesToSend = nonLoadingMessages.slice(-5);
// Call the bot service with the filtered messages
this.chatbotService.getBotResponse(messagesToSend, selectedProgram).subscribe({
@@ -126,6 +134,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
const formattedResponse = this.formatResponseText(response.answer);
this.messages.push({ message: formattedResponse, type: 'system' });
this.needScrollToBottom = true;
+ this.disableSending = false;
},
error: (error) => {
console.error('Error fetching response:', error);
@@ -137,6 +146,7 @@ export class ChatComponent implements OnInit, AfterViewChecked {
type: 'system'
});
this.needScrollToBottom = true;
+ this.disableSending = false;
}
});
}
diff --git a/src/app/services/chatbot.service.ts b/src/app/services/chatbot.service.ts
index ff416ec..4258e56 100644
--- a/src/app/services/chatbot.service.ts
+++ b/src/app/services/chatbot.service.ts
@@ -1,7 +1,7 @@
-import { HttpClient, HttpHeaders } from '@angular/common/http';
+import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { ChatMessage } from '../chat/chat.component';
-import { Observable, switchMap } from 'rxjs';
+import { catchError, Observable, switchMap, throwError } from 'rxjs';
import { environment } from '../../environments/environment';
import { AuthService } from './auth.service';
@@ -22,14 +22,52 @@ export class ChatbotService {
getBotResponse(chatHistory: ChatMessage[], study_program: string): Observable {
const token = this.authService.getToken();
+
+ const makeRequest = (authToken: string): Observable => {
+ return this.sendBotRequest(authToken, chatHistory, study_program);
+ };
+
if (token) {
- return this.sendBotRequest(token, chatHistory, study_program);
+ return makeRequest(token).pipe(
+ catchError((error: HttpErrorResponse) => {
+ if (error.status === 401 || error.status === 403) {
+ // Token might have expired, try to re-authenticate
+ return this.authService.login().pipe(
+ switchMap(() => {
+ const newToken = this.authService.getToken();
+ if (newToken) {
+ return makeRequest(newToken);
+ } else {
+ // Login failed to return a token
+ return throwError(() => new Error('Failed to obtain new token after re-authentication.'));
+ }
+ }),
+ catchError(loginError => {
+ // Handle login failure
+ return throwError(() => loginError);
+ })
+ );
+ } else {
+ // Other errors
+ return throwError(() => error);
+ }
+ })
+ );
} else {
- // Login if no token is stored, then proceed with the bot request
+ // No token available, attempt to login
return this.authService.login().pipe(
switchMap(() => {
const newToken = this.authService.getToken();
- return this.sendBotRequest(newToken, chatHistory, study_program);
+ if (newToken) {
+ return makeRequest(newToken);
+ } else {
+ // Login failed to return a token
+ return throwError(() => new Error('Failed to obtain token after login.'));
+ }
+ }),
+ catchError(loginError => {
+ // Handle login failure
+ return throwError(() => loginError);
})
);
}